@letta-ai/letta-code 0.30.18 → 0.30.19

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
@@ -5488,7 +5488,7 @@ var package_default;
5488
5488
  var init_package = __esm(() => {
5489
5489
  package_default = {
5490
5490
  name: "@letta-ai/letta-code",
5491
- version: "0.30.18",
5491
+ version: "0.30.19",
5492
5492
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
5493
5493
  type: "module",
5494
5494
  packageManager: "bun@1.3.0",
@@ -149321,6 +149321,7 @@ Usage notes:
149321
149321
  - Write a clear, concise user-facing description of what this command does. This description may be shown directly in chat as part of a status row like \`Running command: <description>\` or \`Ran command: <description>\`. Describe the command's purpose, not its shell syntax. For simple commands, keep it brief (5-10 words). For complex commands (piped commands, obscure flags, or anything hard to understand at a glance), add enough context to clarify what it does.
149322
149322
  - If the output exceeds 30000 characters, output will be truncated before being returned to you.
149323
149323
  - You can use the \`run_in_background\` parameter to run the command in the background. Only use this if you don't need the result immediately and are OK being notified when the command completes later. You do not need to check the output right away - you'll be notified when it finishes. You do not need to use '&' at the end of the command when using this parameter.
149324
+ - Pick between \`run_in_background\` and the Monitor tool by how many notifications you need. **One** ("tell me when the server is ready / the build finishes") → Bash with \`run_in_background\` and a command that exits when the condition is true, e.g. \`until grep -q "Ready in" dev.log; do sleep 0.5; done\`. You get a single completion notification when it exits. **One per occurrence** ("tell me every time an ERROR line appears") → use Monitor: each stdout line is an event — you keep working and notifications arrive in the chat. Foreground \`sleep\` is blocked; background the wait (\`run_in_background\` or Monitor) instead of polling BashOutput, and keep working.
149324
149325
 
149325
149326
  - Avoid using Bash with the \`find\`, \`grep\`, \`cat\`, \`head\`, \`tail\`, \`sed\`, \`awk\`, or \`echo\` commands, unless explicitly instructed or when these commands are truly necessary for the task. Instead, always prefer using the dedicated tools for these commands:
149326
149327
  - File search: Use Glob (NOT find or ls)
@@ -149435,6 +149436,7 @@ var BashOutput_default = `# BashOutput
149435
149436
  - Returns stdout and stderr output along with shell status
149436
149437
  - Supports optional regex filtering to show only lines matching a pattern
149437
149438
  - Use this tool when you need to monitor or check the output of a long-running shell
149439
+ - If you are repeatedly calling this tool waiting for a recurring pattern to appear ("tell me every time an ERROR line appears"), stop polling and use the Monitor tool instead: each stdout line is an event — you keep working and notifications arrive in the chat
149438
149440
  - Shell IDs can be found using the /bg command
149439
149441
  - If the accumulated output exceeds 30,000 characters, it will be truncated before being returned to you
149440
149442
  `;
@@ -153572,6 +153574,53 @@ var init_worktree_ownership = __esm(() => {
153572
153574
  ]);
153573
153575
  });
153574
153576
 
153577
+ // src/tools/impl/foreground-sleep.ts
153578
+ function commandRunsForegroundSleep(command) {
153579
+ const segments = splitShellSegmentsAllowCommandSubstitution(command) ?? splitShellSegments(command);
153580
+ if (!segments) {
153581
+ return false;
153582
+ }
153583
+ for (const segment of segments) {
153584
+ for (const word of tokenizeShellWords(segment)) {
153585
+ if (SHELL_KEYWORDS.has(word)) {
153586
+ continue;
153587
+ }
153588
+ if (ASSIGNMENT_PREFIX.test(word)) {
153589
+ continue;
153590
+ }
153591
+ if (word.split("/").pop() === "sleep") {
153592
+ return true;
153593
+ }
153594
+ break;
153595
+ }
153596
+ }
153597
+ return false;
153598
+ }
153599
+ var FOREGROUND_SLEEP_BLOCKED_MESSAGE = 'Foreground `sleep` is blocked — it stalls the session while nothing happens. Run the wait in the background and keep working: use Bash with `run_in_background` and a command that exits when the condition is true, e.g. `until grep -q "Ready in" dev.log; do sleep 0.5; done`. You get a single completion notification when it exits. For one notification per occurrence ("tell me every time an ERROR line appears"), use the Monitor tool instead. `sleep` inside `run_in_background` commands and Monitor scripts is fine.', SHELL_KEYWORDS, ASSIGNMENT_PREFIX;
153600
+ var init_foreground_sleep = __esm(() => {
153601
+ SHELL_KEYWORDS = new Set([
153602
+ "if",
153603
+ "then",
153604
+ "elif",
153605
+ "else",
153606
+ "fi",
153607
+ "while",
153608
+ "until",
153609
+ "do",
153610
+ "done",
153611
+ "for",
153612
+ "case",
153613
+ "esac",
153614
+ "{",
153615
+ "}",
153616
+ "(",
153617
+ ")",
153618
+ "!",
153619
+ "time"
153620
+ ]);
153621
+ ASSIGNMENT_PREFIX = /^[A-Za-z_][A-Za-z0-9_]*=/;
153622
+ });
153623
+
153575
153624
  // src/tools/impl/process_manager.ts
153576
153625
  var exports_process_manager = {};
153577
153626
  __export(exports_process_manager, {
@@ -155762,6 +155811,12 @@ Output file: ${outputFile}`
155762
155811
  status: "success"
155763
155812
  };
155764
155813
  }
155814
+ if (commandRunsForegroundSleep(command)) {
155815
+ return {
155816
+ content: [{ type: "text", text: FOREGROUND_SLEEP_BLOCKED_MESSAGE }],
155817
+ status: "error"
155818
+ };
155819
+ }
155765
155820
  const effectiveTimeout = Math.min(Math.max(timeout, 1), 600000);
155766
155821
  try {
155767
155822
  const { stdout, stderr, exitCode } = await spawnCommand(command, {
@@ -155833,6 +155888,7 @@ var init_bash = __esm(() => {
155833
155888
  init_message_queue_bridge();
155834
155889
  init_task_notifications();
155835
155890
  init_worktree_ownership();
155891
+ init_foreground_sleep();
155836
155892
  init_process_manager();
155837
155893
  init_shell_env();
155838
155894
  init_shell_launchers();
@@ -157525,7 +157581,6 @@ function notifyStreamObserversRuntimeStopped(listener) {
157525
157581
  // src/websocket/listener/protocol-outbound.ts
157526
157582
  var exports_protocol_outbound = {};
157527
157583
  __export(exports_protocol_outbound, {
157528
- scheduleQueueEmit: () => scheduleQueueEmit,
157529
157584
  isSystemReminderPart: () => isSystemReminderPart,
157530
157585
  emitSubagentStateUpdate: () => emitSubagentStateUpdate,
157531
157586
  emitSubagentStateIfOpen: () => emitSubagentStateIfOpen,
@@ -157734,6 +157789,9 @@ function isStreamChannelMessage(type3) {
157734
157789
  return STREAM_CHANNEL_MESSAGE_TYPES.has(type3);
157735
157790
  }
157736
157791
  function classifyOutboundFrame(message) {
157792
+ if (message.type === "update_queue" && (message.removed?.length ?? 0) > 0) {
157793
+ return "critical";
157794
+ }
157737
157795
  return COALESCABLE_STATUS_MESSAGE_TYPES.has(message.type) ? "status" : "critical";
157738
157796
  }
157739
157797
  function emitProtocolV2Message(socket, runtime, message, scope, routing) {
@@ -157851,7 +157909,7 @@ function emitDeviceStatusIfOpen(runtime, scope) {
157851
157909
  emitDeviceStatusUpdate(transport, runtime, scope);
157852
157910
  }
157853
157911
  }
157854
- function emitQueueUpdate(socket, runtime, scope, routing = TO_SUBSCRIBERS) {
157912
+ function emitQueueUpdate(socket, runtime, scope, routing = TO_SUBSCRIBERS, removed = []) {
157855
157913
  const listener = getListenerRuntime(runtime);
157856
157914
  if (!listener) {
157857
157915
  return;
@@ -157859,7 +157917,8 @@ function emitQueueUpdate(socket, runtime, scope, routing = TO_SUBSCRIBERS) {
157859
157917
  const resolvedScope = getScopeForRuntime(runtime, scope);
157860
157918
  const message = {
157861
157919
  type: "update_queue",
157862
- queue: buildQueueSnapshot(runtime, resolvedScope)
157920
+ queue: buildQueueSnapshot(runtime, resolvedScope),
157921
+ removed: [...removed]
157863
157922
  };
157864
157923
  emitProtocolV2Message(socket, runtime, message, resolvedScope, routing);
157865
157924
  }
@@ -157955,11 +158014,11 @@ function emitDequeuedUserMessage(socket, runtime, incoming, batch) {
157955
158014
  conversation_id: incoming.conversationId
157956
158015
  });
157957
158016
  }
157958
- function emitQueueUpdateIfOpen(runtime, scope) {
158017
+ function emitQueueUpdateIfOpen(runtime, scope, removed = []) {
157959
158018
  const listener = getListenerRuntime(runtime);
157960
158019
  const transport = listener?.transport ?? listener?.socket;
157961
158020
  if (transport && isListenerTransportOpen(transport)) {
157962
- emitQueueUpdate(transport, runtime, scope);
158021
+ emitQueueUpdate(transport, runtime, scope, TO_SUBSCRIBERS, removed);
157963
158022
  }
157964
158023
  }
157965
158024
  function emitDeviceStatusUpdateIfChanged(socket, runtime, scope, options3, routing = TO_SUBSCRIBERS) {
@@ -158035,18 +158094,6 @@ function emitSubagentStateIfOpen(runtime, scope) {
158035
158094
  emitSubagentStateUpdate(transport, runtime, scope);
158036
158095
  }
158037
158096
  }
158038
- function scheduleQueueEmit(runtime, scope) {
158039
- runtime.pendingQueueEmitScope = scope;
158040
- if (runtime.queueEmitScheduled)
158041
- return;
158042
- runtime.queueEmitScheduled = true;
158043
- queueMicrotask(() => {
158044
- runtime.queueEmitScheduled = false;
158045
- const emitScope = runtime.pendingQueueEmitScope;
158046
- runtime.pendingQueueEmitScope = undefined;
158047
- emitQueueUpdateIfOpen(runtime, emitScope);
158048
- });
158049
- }
158050
158097
  function createLifecycleMessageBase(messageType, runId) {
158051
158098
  return {
158052
158099
  id: `lifecycle-${crypto.randomUUID()}`,
@@ -239488,7 +239535,7 @@ var init_utils5 = __esm(() => {
239488
239535
  init_media();
239489
239536
  TELEGRAM_LIFECYCLE_ERROR_DEDUPE_TTL_MS = 6 * 60 * 60 * 1000;
239490
239537
  TELEGRAM_LIFECYCLE_ERROR_REPORT_TTL_MS = 6 * 60 * 60 * 1000;
239491
- TELEGRAM_TYPING_MAX_MS = 5 * 60 * 1000;
239538
+ TELEGRAM_TYPING_MAX_MS = 6 * 60 * 60 * 1000;
239492
239539
  });
239493
239540
 
239494
239541
  // src/channels/telegram/account-display.ts
@@ -240160,9 +240207,22 @@ async function stopTelegramBotQuietly(telegramBot, options3) {
240160
240207
  }
240161
240208
  var DEFAULT_TELEGRAM_INIT_TIMEOUT_MS = 15000, DEFAULT_TELEGRAM_START_TIMEOUT_MS = 20000, TELEGRAM_FAILED_START_STOP_TIMEOUT_MS = 5000;
240162
240209
 
240210
+ // src/channels/typing-controller-timers.ts
240211
+ var SYSTEM_TYPING_CONTROLLER_TIMERS;
240212
+ var init_typing_controller_timers = __esm(() => {
240213
+ SYSTEM_TYPING_CONTROLLER_TIMERS = {
240214
+ setInterval: (callback, delayMs) => setInterval(callback, delayMs),
240215
+ clearInterval: (handle2) => clearInterval(handle2),
240216
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
240217
+ clearTimeout: (handle2) => clearTimeout(handle2)
240218
+ };
240219
+ });
240220
+
240163
240221
  // src/channels/telegram/typing-controller.ts
240164
240222
  function createTelegramTypingController(deps) {
240165
- const typingByChatId = new Map;
240223
+ const timers = deps.timers ?? SYSTEM_TYPING_CONTROLLER_TIMERS;
240224
+ const typingByTarget = new Map;
240225
+ const lastOutboundAtByTarget = new Map;
240166
240226
  function getChatId(source2) {
240167
240227
  if (source2.channel !== "telegram")
240168
240228
  return null;
@@ -240182,59 +240242,93 @@ function createTelegramTypingController(deps) {
240182
240242
  source2.conversationId
240183
240243
  ].join(":");
240184
240244
  }
240185
- function clearChat(chatId) {
240186
- const entry = typingByChatId.get(chatId);
240245
+ function getTargetKey(source2) {
240246
+ const chatId = getChatId(source2);
240247
+ if (!chatId)
240248
+ return null;
240249
+ return targetKey(chatId, source2.threadId);
240250
+ }
240251
+ function targetKey(chatId, threadId) {
240252
+ return [chatId, threadId ?? ""].join(":");
240253
+ }
240254
+ function clearTarget(targetKey2) {
240255
+ const entry = typingByTarget.get(targetKey2);
240187
240256
  if (!entry)
240188
240257
  return;
240189
- clearInterval(entry.timer);
240190
- clearTimeout(entry.timeout);
240191
- typingByChatId.delete(chatId);
240258
+ timers.clearInterval(entry.timer);
240259
+ timers.clearTimeout(entry.timeout);
240260
+ typingByTarget.delete(targetKey2);
240261
+ lastOutboundAtByTarget.delete(targetKey2);
240262
+ }
240263
+ function touchWatchdog(targetKey2) {
240264
+ const entry = typingByTarget.get(targetKey2);
240265
+ if (!entry)
240266
+ return;
240267
+ timers.clearTimeout(entry.timeout);
240268
+ entry.timeout = timers.setTimeout(() => clearTarget(targetKey2), TELEGRAM_TYPING_MAX_MS);
240269
+ entry.timeout.unref?.();
240192
240270
  }
240193
240271
  function start(source2) {
240194
240272
  const chatId = getChatId(source2);
240273
+ const targetKey2 = getTargetKey(source2);
240195
240274
  const sourceKey = getSourceKey(source2);
240196
- if (!chatId || !sourceKey)
240275
+ if (!chatId || !targetKey2 || !sourceKey)
240197
240276
  return;
240198
- const existing = typingByChatId.get(chatId);
240277
+ const threadId = source2.threadId ?? null;
240278
+ const existing = typingByTarget.get(targetKey2);
240199
240279
  if (existing) {
240200
240280
  existing.sourceKeys.add(sourceKey);
240281
+ touchWatchdog(targetKey2);
240201
240282
  return;
240202
240283
  }
240203
- deps.sendTypingAction(chatId);
240204
- const timer = setInterval(() => {
240205
- deps.sendTypingAction(chatId);
240284
+ deps.sendTypingAction(chatId, threadId);
240285
+ const timer = timers.setInterval(() => {
240286
+ const lastOutboundAt = lastOutboundAtByTarget.get(targetKey2) ?? 0;
240287
+ if (Date.now() - lastOutboundAt < OUTBOUND_TYPING_SUPPRESSION_MS)
240288
+ return;
240289
+ deps.sendTypingAction(chatId, threadId);
240206
240290
  }, TELEGRAM_TYPING_REFRESH_MS);
240207
- const timeout = setTimeout(() => clearChat(chatId), TELEGRAM_TYPING_MAX_MS);
240291
+ const timeout = timers.setTimeout(() => clearTarget(targetKey2), TELEGRAM_TYPING_MAX_MS);
240208
240292
  timer.unref?.();
240209
240293
  timeout.unref?.();
240210
- typingByChatId.set(chatId, {
240294
+ typingByTarget.set(targetKey2, {
240211
240295
  sourceKeys: new Set([sourceKey]),
240212
240296
  timer,
240213
240297
  timeout
240214
240298
  });
240215
240299
  }
240300
+ function markOutbound(chatId, threadId) {
240301
+ const key2 = targetKey(chatId, threadId);
240302
+ if (!typingByTarget.has(key2))
240303
+ return;
240304
+ lastOutboundAtByTarget.set(key2, Date.now());
240305
+ touchWatchdog(key2);
240306
+ }
240216
240307
  function stop(source2) {
240217
- const chatId = getChatId(source2);
240308
+ const targetKey2 = getTargetKey(source2);
240218
240309
  const sourceKey = getSourceKey(source2);
240219
- if (!chatId || !sourceKey)
240310
+ if (!targetKey2 || !sourceKey)
240220
240311
  return;
240221
- const entry = typingByChatId.get(chatId);
240312
+ const entry = typingByTarget.get(targetKey2);
240222
240313
  if (!entry)
240223
240314
  return;
240224
240315
  entry.sourceKeys.delete(sourceKey);
240225
240316
  if (entry.sourceKeys.size === 0)
240226
- clearChat(chatId);
240317
+ clearTarget(targetKey2);
240227
240318
  }
240228
240319
  function clearAll() {
240229
- for (const entry of typingByChatId.values()) {
240230
- clearInterval(entry.timer);
240231
- clearTimeout(entry.timeout);
240320
+ for (const entry of typingByTarget.values()) {
240321
+ timers.clearInterval(entry.timer);
240322
+ timers.clearTimeout(entry.timeout);
240232
240323
  }
240233
- typingByChatId.clear();
240324
+ typingByTarget.clear();
240325
+ lastOutboundAtByTarget.clear();
240234
240326
  }
240235
- return { clearAll, clearChat, getChatId, start, stop };
240327
+ return { clearAll, getChatId, markOutbound, start, stop };
240236
240328
  }
240329
+ var OUTBOUND_TYPING_SUPPRESSION_MS = 1000;
240237
240330
  var init_typing_controller = __esm(() => {
240331
+ init_typing_controller_timers();
240238
240332
  init_utils5();
240239
240333
  });
240240
240334
 
@@ -240283,12 +240377,14 @@ function createTelegramAdapter(config3) {
240283
240377
  async function dispatchInbound(inbound) {
240284
240378
  await debouncer.enqueue({ inbound });
240285
240379
  }
240286
- async function sendTypingAction(chatId) {
240380
+ async function sendTypingAction(chatId, threadId) {
240287
240381
  if (!running)
240288
240382
  return;
240289
240383
  try {
240290
240384
  const telegramBot = await ensureBot();
240291
- await telegramBot.api.sendChatAction(chatId, "typing");
240385
+ await telegramBot.api.sendChatAction(chatId, "typing", {
240386
+ ...threadId ? { message_thread_id: Number(threadId) } : {}
240387
+ });
240292
240388
  } catch (error54) {
240293
240389
  console.warn(`[Telegram] Failed to send typing action for chat ${chatId}:`, error54 instanceof Error ? error54.message : error54);
240294
240390
  }
@@ -240665,7 +240761,7 @@ function createTelegramAdapter(config3) {
240665
240761
  } else {
240666
240762
  await telegramBot.api.setMessageReaction(msg.chatId, Number(targetMessageId), []);
240667
240763
  }
240668
- typing.clearChat(msg.chatId);
240764
+ typing.markOutbound(msg.chatId, resolveTelegramOutboundThreadId(msg));
240669
240765
  return { messageId: targetMessageId };
240670
240766
  }
240671
240767
  if (msg.mediaPath) {
@@ -240692,14 +240788,14 @@ function createTelegramAdapter(config3) {
240692
240788
  return await telegramBot.api.sendDocument(msg.chatId, inputFile, options3);
240693
240789
  }
240694
240790
  })();
240695
- typing.clearChat(msg.chatId);
240791
+ typing.markOutbound(msg.chatId, resolveTelegramOutboundThreadId(msg));
240696
240792
  return { messageId: String(result2.message_id) };
240697
240793
  }
240698
240794
  if (msg.richMessage) {
240699
240795
  const raw2 = telegramBot.api.raw;
240700
240796
  try {
240701
240797
  const result2 = await raw2.sendRichMessage(buildTelegramRichMessagePayload(msg));
240702
- typing.clearChat(msg.chatId);
240798
+ typing.markOutbound(msg.chatId, resolveTelegramOutboundThreadId(msg));
240703
240799
  return { messageId: String(result2.message_id) };
240704
240800
  } catch (error54) {
240705
240801
  if (!shouldFallbackTelegramRichMessage(error54)) {
@@ -240722,7 +240818,7 @@ function createTelegramAdapter(config3) {
240722
240818
  opts.parse_mode = msg.parseMode;
240723
240819
  }
240724
240820
  const result = await telegramBot.api.sendMessage(msg.chatId, msg.text, opts);
240725
- typing.clearChat(msg.chatId);
240821
+ typing.markOutbound(msg.chatId, threadId);
240726
240822
  return { messageId: String(result.message_id) };
240727
240823
  },
240728
240824
  async sendDirectReply(chatId, text2, options3) {
@@ -240737,11 +240833,13 @@ function createTelegramAdapter(config3) {
240737
240833
  ...threadId ? { message_thread_id: Number(threadId) } : {},
240738
240834
  ...reply_parameters ? { reply_parameters } : {}
240739
240835
  });
240836
+ typing.markOutbound(chatId, threadId);
240740
240837
  },
240741
240838
  async handleTurnLifecycleEvent(event2) {
240742
240839
  if (!running)
240743
240840
  return;
240744
240841
  if (event2.type === "queued") {
240842
+ typing.start(event2.source);
240745
240843
  return;
240746
240844
  }
240747
240845
  if (event2.type === "processing") {
@@ -240781,7 +240879,7 @@ function createTelegramAdapter(config3) {
240781
240879
  ...threadId ? { message_thread_id: Number(threadId) } : {},
240782
240880
  ...reply_parameters ? { reply_parameters } : {}
240783
240881
  });
240784
- typing.clearChat(event2.source.chatId);
240882
+ typing.stop(event2.source);
240785
240883
  },
240786
240884
  onMessage: undefined
240787
240885
  };
@@ -246743,6 +246841,126 @@ var init_utils7 = __esm(() => {
246743
246841
  init_lifecycle_error();
246744
246842
  });
246745
246843
 
246844
+ // src/channels/discord/typing-controller.ts
246845
+ function createDiscordTypingController(deps) {
246846
+ const timers = deps.timers ?? SYSTEM_TYPING_CONTROLLER_TIMERS;
246847
+ const typingByChannelId = new Map;
246848
+ const lastTypingOutputAtByChannelId = new Map;
246849
+ function getChannelId(source2) {
246850
+ if (source2.channel !== "discord")
246851
+ return null;
246852
+ const channelId = source2.threadId ?? source2.chatId;
246853
+ return isNonEmptyString8(channelId) ? channelId : null;
246854
+ }
246855
+ function getSourceKey(source2) {
246856
+ const channelId = getChannelId(source2);
246857
+ if (!channelId)
246858
+ return null;
246859
+ return [
246860
+ source2.accountId ?? "",
246861
+ channelId,
246862
+ source2.messageId ?? "",
246863
+ source2.agentId,
246864
+ source2.conversationId
246865
+ ].join(":");
246866
+ }
246867
+ function clearChannel(channelId) {
246868
+ const entry = typingByChannelId.get(channelId);
246869
+ if (!entry)
246870
+ return;
246871
+ timers.clearInterval(entry.timer);
246872
+ timers.clearTimeout(entry.timeout);
246873
+ typingByChannelId.delete(channelId);
246874
+ lastTypingOutputAtByChannelId.delete(channelId);
246875
+ }
246876
+ function touchWatchdog(channelId) {
246877
+ const entry = typingByChannelId.get(channelId);
246878
+ if (!entry)
246879
+ return;
246880
+ timers.clearTimeout(entry.timeout);
246881
+ entry.timeout = timers.setTimeout(() => {
246882
+ clearChannel(channelId);
246883
+ }, DISCORD_TYPING_MAX_MS);
246884
+ entry.timeout.unref?.();
246885
+ }
246886
+ async function start(source2) {
246887
+ const channelId = getChannelId(source2);
246888
+ const sourceKey = getSourceKey(source2);
246889
+ if (!channelId || !sourceKey)
246890
+ return;
246891
+ const existing = typingByChannelId.get(channelId);
246892
+ if (existing) {
246893
+ existing.sourceKeys.add(sourceKey);
246894
+ touchWatchdog(channelId);
246895
+ return;
246896
+ }
246897
+ let entry;
246898
+ const timer = timers.setInterval(() => {
246899
+ if (Date.now() - (lastTypingOutputAtByChannelId.get(channelId) ?? 0) < OUTBOUND_TYPING_SUPPRESSION_MS2)
246900
+ return;
246901
+ deps.sendTypingAction(channelId).then((ok) => {
246902
+ if (typingByChannelId.get(channelId) !== entry)
246903
+ return;
246904
+ if (!ok) {
246905
+ clearChannel(channelId);
246906
+ }
246907
+ });
246908
+ }, DISCORD_TYPING_REFRESH_MS);
246909
+ timer.unref?.();
246910
+ entry = {
246911
+ sourceKeys: new Set([sourceKey]),
246912
+ timer,
246913
+ timeout: timers.setTimeout(() => {
246914
+ clearChannel(channelId);
246915
+ }, DISCORD_TYPING_MAX_MS)
246916
+ };
246917
+ entry.timeout.unref?.();
246918
+ typingByChannelId.set(channelId, entry);
246919
+ if (!await deps.sendTypingAction(channelId)) {
246920
+ const current = typingByChannelId.get(channelId);
246921
+ if (current === entry && current.sourceKeys.size === 1 && current.sourceKeys.has(sourceKey)) {
246922
+ clearChannel(channelId);
246923
+ }
246924
+ return;
246925
+ }
246926
+ touchWatchdog(channelId);
246927
+ }
246928
+ function stop(source2) {
246929
+ const channelId = getChannelId(source2);
246930
+ const sourceKey = getSourceKey(source2);
246931
+ if (!channelId || !sourceKey)
246932
+ return;
246933
+ const entry = typingByChannelId.get(channelId);
246934
+ if (!entry)
246935
+ return;
246936
+ entry.sourceKeys.delete(sourceKey);
246937
+ if (entry.sourceKeys.size === 0) {
246938
+ clearChannel(channelId);
246939
+ }
246940
+ }
246941
+ function markOutbound(channelId) {
246942
+ if (!typingByChannelId.has(channelId))
246943
+ return;
246944
+ lastTypingOutputAtByChannelId.set(channelId, Date.now());
246945
+ touchWatchdog(channelId);
246946
+ }
246947
+ function clearAll() {
246948
+ for (const entry of typingByChannelId.values()) {
246949
+ timers.clearInterval(entry.timer);
246950
+ timers.clearTimeout(entry.timeout);
246951
+ }
246952
+ typingByChannelId.clear();
246953
+ lastTypingOutputAtByChannelId.clear();
246954
+ }
246955
+ return { clearAll, markOutbound, start, stop };
246956
+ }
246957
+ var OUTBOUND_TYPING_SUPPRESSION_MS2 = 1000, DISCORD_TYPING_REFRESH_MS = 8000, DISCORD_TYPING_MAX_MS;
246958
+ var init_typing_controller2 = __esm(() => {
246959
+ init_typing_controller_timers();
246960
+ init_utils7();
246961
+ DISCORD_TYPING_MAX_MS = 6 * 60 * 60 * 1000;
246962
+ });
246963
+
246746
246964
  // src/channels/discord/adapter.ts
246747
246965
  import { basename as basename16 } from "node:path";
246748
246966
  function createDiscordAdapter(config3) {
@@ -246753,7 +246971,22 @@ function createDiscordAdapter(config3) {
246753
246971
  const lifecycleStateByMessageKey = new Map;
246754
246972
  const lifecycleOperationByMessageKey = new Map;
246755
246973
  const lifecycleErrorReplyKeys = new Map;
246756
- const typingByChannelId = new Map;
246974
+ const typing = createDiscordTypingController({
246975
+ sendTypingAction: async (channelId) => {
246976
+ if (!running || !client)
246977
+ return false;
246978
+ try {
246979
+ const channel = await client.channels.fetch(channelId);
246980
+ if (!isDiscordTypingChannel(channel))
246981
+ return false;
246982
+ await channel.sendTyping();
246983
+ return true;
246984
+ } catch (error54) {
246985
+ console.warn(`[Discord] Failed to send typing indicator for ${channelId}:`, error54 instanceof Error ? error54.message : error54);
246986
+ return false;
246987
+ }
246988
+ }
246989
+ });
246757
246990
  function pruneSeenIngressMessageKeys(now = Date.now()) {
246758
246991
  for (const [key2, expiresAt] of seenIngressMessageKeys) {
246759
246992
  if (expiresAt <= now) {
@@ -246799,24 +247032,6 @@ function createDiscordAdapter(config3) {
246799
247032
  source2.conversationId
246800
247033
  ].join(":");
246801
247034
  }
246802
- function getTypingChannelId(source2) {
246803
- if (source2.channel !== "discord")
246804
- return null;
246805
- const channelId = source2.threadId ?? source2.chatId;
246806
- return isNonEmptyString8(channelId) ? channelId : null;
246807
- }
246808
- function getTypingSourceKey(source2) {
246809
- const channelId = getTypingChannelId(source2);
246810
- if (!channelId)
246811
- return null;
246812
- return [
246813
- source2.accountId ?? "",
246814
- channelId,
246815
- source2.messageId ?? "",
246816
- source2.agentId,
246817
- source2.conversationId
246818
- ].join(":");
246819
- }
246820
247035
  function pruneLifecycleState(now = Date.now()) {
246821
247036
  for (const [key2, entry] of lifecycleStateByMessageKey) {
246822
247037
  if (entry.updatedAt + LIFECYCLE_STATE_TTL_MS <= now) {
@@ -246894,83 +247109,6 @@ function createDiscordAdapter(config3) {
246894
247109
  ...reply ?? {}
246895
247110
  });
246896
247111
  }
246897
- async function sendTypingAction(channelId) {
246898
- if (!running || !client)
246899
- return false;
246900
- try {
246901
- const channel = await client.channels.fetch(channelId);
246902
- if (!isDiscordTypingChannel(channel))
246903
- return false;
246904
- await channel.sendTyping();
246905
- return true;
246906
- } catch (error54) {
246907
- console.warn(`[Discord] Failed to send typing indicator for ${channelId}:`, error54 instanceof Error ? error54.message : error54);
246908
- return false;
246909
- }
246910
- }
246911
- async function startTypingForSource(source2) {
246912
- const channelId = getTypingChannelId(source2);
246913
- const sourceKey = getTypingSourceKey(source2);
246914
- if (!channelId || !sourceKey)
246915
- return;
246916
- const existing = typingByChannelId.get(channelId);
246917
- if (existing) {
246918
- existing.sourceKeys.add(sourceKey);
246919
- return;
246920
- }
246921
- if (!await sendTypingAction(channelId)) {
246922
- return;
246923
- }
246924
- const timer = setInterval(() => {
246925
- sendTypingAction(channelId).then((ok) => {
246926
- if (!ok) {
246927
- clearTypingForChannel(channelId);
246928
- }
246929
- });
246930
- }, DISCORD_TYPING_REFRESH_MS);
246931
- const timeout = setTimeout(() => {
246932
- clearTypingForChannel(channelId);
246933
- }, DISCORD_TYPING_MAX_MS);
246934
- if (typeof timer.unref === "function") {
246935
- timer.unref?.();
246936
- }
246937
- if (typeof timeout.unref === "function") {
246938
- timeout.unref?.();
246939
- }
246940
- typingByChannelId.set(channelId, {
246941
- sourceKeys: new Set([sourceKey]),
246942
- timer,
246943
- timeout
246944
- });
246945
- }
246946
- function stopTypingForSource(source2) {
246947
- const channelId = getTypingChannelId(source2);
246948
- const sourceKey = getTypingSourceKey(source2);
246949
- if (!channelId || !sourceKey)
246950
- return;
246951
- const entry = typingByChannelId.get(channelId);
246952
- if (!entry)
246953
- return;
246954
- entry.sourceKeys.delete(sourceKey);
246955
- if (entry.sourceKeys.size === 0) {
246956
- clearTypingForChannel(channelId);
246957
- }
246958
- }
246959
- function clearTypingForChannel(channelId) {
246960
- const entry = typingByChannelId.get(channelId);
246961
- if (!entry)
246962
- return;
246963
- clearInterval(entry.timer);
246964
- clearTimeout(entry.timeout);
246965
- typingByChannelId.delete(channelId);
246966
- }
246967
- function clearAllTyping() {
246968
- for (const entry of typingByChannelId.values()) {
246969
- clearInterval(entry.timer);
246970
- clearTimeout(entry.timeout);
246971
- }
246972
- typingByChannelId.clear();
246973
- }
246974
247112
  function scheduleLifecycleTransition(source2, nextState) {
246975
247113
  const key2 = getLifecycleMessageKey(source2);
246976
247114
  if (!key2)
@@ -247273,7 +247411,7 @@ function createDiscordAdapter(config3) {
247273
247411
  async stop() {
247274
247412
  if (!running || !client)
247275
247413
  return;
247276
- clearAllTyping();
247414
+ typing.clearAll();
247277
247415
  client.destroy();
247278
247416
  client = null;
247279
247417
  running = false;
@@ -247291,6 +247429,7 @@ function createDiscordAdapter(config3) {
247291
247429
  if (!running)
247292
247430
  return;
247293
247431
  if (event2.type === "queued") {
247432
+ await typing.start(event2.source);
247294
247433
  if (config3.acknowledgeMessageReaction) {
247295
247434
  await scheduleLifecycleTransition(event2.source, "queued");
247296
247435
  }
@@ -247298,12 +247437,12 @@ function createDiscordAdapter(config3) {
247298
247437
  }
247299
247438
  if (event2.type === "processing") {
247300
247439
  for (const source2 of event2.sources) {
247301
- await startTypingForSource(source2);
247440
+ await typing.start(source2);
247302
247441
  }
247303
247442
  return;
247304
247443
  }
247305
247444
  for (const source2 of event2.sources) {
247306
- stopTypingForSource(source2);
247445
+ typing.stop(source2);
247307
247446
  }
247308
247447
  const nextState = event2.outcome === "completed" ? "completed" : event2.outcome === "cancelled" ? "cancelled" : "error";
247309
247448
  if (config3.acknowledgeMessageReaction) {
@@ -247350,7 +247489,7 @@ function createDiscordAdapter(config3) {
247350
247489
  } else {
247351
247490
  await message.react(emoji3);
247352
247491
  }
247353
- clearTypingForChannel(targetChannelId2);
247492
+ typing.markOutbound(targetChannelId2);
247354
247493
  return { messageId: targetMessageId };
247355
247494
  }
247356
247495
  if (msg.mediaPath) {
@@ -247370,7 +247509,7 @@ function createDiscordAdapter(config3) {
247370
247509
  }
247371
247510
  ]
247372
247511
  });
247373
- clearTypingForChannel(targetChannelId2);
247512
+ typing.markOutbound(targetChannelId2);
247374
247513
  return { messageId: result.id };
247375
247514
  }
247376
247515
  const targetChannelId = msg.threadId ?? msg.chatId;
@@ -247388,7 +247527,7 @@ function createDiscordAdapter(config3) {
247388
247527
  });
247389
247528
  lastMessageId = result.id;
247390
247529
  }
247391
- clearTypingForChannel(targetChannelId);
247530
+ typing.markOutbound(targetChannelId);
247392
247531
  return { messageId: lastMessageId };
247393
247532
  },
247394
247533
  async sendDirectReply(chatId, text2, options3) {
@@ -247403,7 +247542,7 @@ function createDiscordAdapter(config3) {
247403
247542
  content: text2,
247404
247543
  ...reply ?? {}
247405
247544
  });
247406
- clearTypingForChannel(chatId);
247545
+ typing.markOutbound(chatId);
247407
247546
  },
247408
247547
  async prepareInboundMessage(msg, options3) {
247409
247548
  if (!options3?.isFirstRouteTurn || msg.channel !== "discord" || msg.chatType !== "channel" || !isNonEmptyString8(msg.threadId) || !client) {
@@ -247448,13 +247587,13 @@ function createDiscordAdapter(config3) {
247448
247587
  };
247449
247588
  return adapter;
247450
247589
  }
247451
- var DISCORD_SPLIT_THRESHOLD = 1900, INGRESS_DEDUPE_TTL_MS = 60000, INGRESS_DEDUPE_MAX = 2000, LIFECYCLE_STATE_TTL_MS, LIFECYCLE_STATE_MAX = 2000, INITIAL_THREAD_HISTORY_LIMIT = 20, DISCORD_TYPING_REFRESH_MS = 8000, DISCORD_TYPING_MAX_MS;
247590
+ var DISCORD_SPLIT_THRESHOLD = 1900, INGRESS_DEDUPE_TTL_MS = 60000, INGRESS_DEDUPE_MAX = 2000, LIFECYCLE_STATE_TTL_MS, LIFECYCLE_STATE_MAX = 2000, INITIAL_THREAD_HISTORY_LIMIT = 20;
247452
247591
  var init_adapter4 = __esm(() => {
247453
247592
  init_media3();
247454
247593
  init_runtime4();
247594
+ init_typing_controller2();
247455
247595
  init_utils7();
247456
247596
  LIFECYCLE_STATE_TTL_MS = 6 * 60 * 60 * 1000;
247457
- DISCORD_TYPING_MAX_MS = 5 * 60 * 1000;
247458
247597
  });
247459
247598
 
247460
247599
  // src/channels/discord/message-actions.ts
@@ -249396,7 +249535,7 @@ function createWhatsAppTypingController(options3) {
249396
249535
  return { start, stop, isActive, clearChat, clearOwner, clearAll };
249397
249536
  }
249398
249537
  var DEFAULT_REFRESH_MS = 12000, DEFAULT_MAX_LIFETIME_MS;
249399
- var init_typing_controller2 = __esm(() => {
249538
+ var init_typing_controller3 = __esm(() => {
249400
249539
  DEFAULT_MAX_LIFETIME_MS = 5 * 60000;
249401
249540
  });
249402
249541
 
@@ -250105,7 +250244,7 @@ var init_adapter5 = __esm(() => {
250105
250244
  init_runtime5();
250106
250245
  init_session2();
250107
250246
  init_state();
250108
- init_typing_controller2();
250247
+ init_typing_controller3();
250109
250248
  STABLE_OPEN_RESET_MS = RECONNECT_WINDOW_MS;
250110
250249
  CLAIM_CONNECTION_STATE = { claimedConnectionState: true };
250111
250250
  });
@@ -253263,15 +253402,143 @@ var init_registry_commands = __esm(() => {
253263
253402
  init_types8();
253264
253403
  });
253265
253404
 
253405
+ // src/channels/control-request-coordinator.ts
253406
+ function getChannelControlRequestScopeKey(params) {
253407
+ return [
253408
+ params.channel,
253409
+ params.accountId ?? "default",
253410
+ params.chatId,
253411
+ params.threadId ?? ""
253412
+ ].join(":");
253413
+ }
253414
+ function cloneEvent(event2) {
253415
+ return structuredClone(event2);
253416
+ }
253417
+
253418
+ class ChannelControlRequestCoordinator {
253419
+ options;
253420
+ pendingById = new Map;
253421
+ requestIdByScope = new Map;
253422
+ constructor(options3) {
253423
+ this.options = options3;
253424
+ }
253425
+ restore(events) {
253426
+ for (const event2 of events) {
253427
+ this.remember(event2, false);
253428
+ }
253429
+ }
253430
+ has(requestId) {
253431
+ return this.pendingById.has(requestId);
253432
+ }
253433
+ getAll() {
253434
+ return Array.from(this.pendingById.values()).map((pending) => ({
253435
+ event: cloneEvent(pending.event),
253436
+ deliveredThisProcess: pending.deliveredThisProcess
253437
+ }));
253438
+ }
253439
+ async register(event2) {
253440
+ const scopeKey = getChannelControlRequestScopeKey(event2.source);
253441
+ const existingRequestId = this.requestIdByScope.get(scopeKey);
253442
+ if (existingRequestId && existingRequestId !== event2.requestId) {
253443
+ await this.clear(existingRequestId);
253444
+ }
253445
+ this.remember(event2, false);
253446
+ await this.options.persist(cloneEvent(event2));
253447
+ await this.deliver(event2.requestId);
253448
+ }
253449
+ async redeliver(requestId) {
253450
+ return this.deliver(requestId);
253451
+ }
253452
+ async handleNativeResponse(input) {
253453
+ const pending = this.pendingById.get(input.requestId);
253454
+ if (!pending)
253455
+ return "expired";
253456
+ const source2 = pending.event.source;
253457
+ if (source2.channel !== input.channel || (source2.accountId ?? "default") !== (input.accountId ?? "default") || source2.chatId !== input.chatId || (source2.threadId ?? null) !== (input.threadId ?? null) || source2.senderId && source2.senderId !== input.senderId) {
253458
+ return "forbidden";
253459
+ }
253460
+ const result = await this.options.deliverResponse(cloneEvent(pending.event), input.response);
253461
+ if (result === "handled" || result === "expired") {
253462
+ await this.clear(input.requestId);
253463
+ }
253464
+ return result;
253465
+ }
253466
+ async tryHandleInbound(input) {
253467
+ if (input.bypass)
253468
+ return false;
253469
+ const requestId = this.requestIdByScope.get(getChannelControlRequestScopeKey(input));
253470
+ if (!requestId)
253471
+ return false;
253472
+ const pending = this.pendingById.get(requestId);
253473
+ if (!pending) {
253474
+ this.requestIdByScope.delete(getChannelControlRequestScopeKey(input));
253475
+ return false;
253476
+ }
253477
+ if (pending.event.source.senderId && pending.event.source.senderId !== input.senderId) {
253478
+ return false;
253479
+ }
253480
+ if (input.channel === "slack" && pending.event.kind === "generic_tool_approval") {
253481
+ return false;
253482
+ }
253483
+ const parsed = parseChannelControlRequestResponse(pending.event, input.text);
253484
+ if (parsed.type === "reprompt") {
253485
+ await this.options.deliverReprompt(cloneEvent(pending.event), input, parsed.message);
253486
+ return true;
253487
+ }
253488
+ const result = await this.options.deliverResponse(cloneEvent(pending.event), parsed.response);
253489
+ if (result === "unavailable") {
253490
+ await this.options.deliverReprompt(cloneEvent(pending.event), input, "I’m reconnecting to Letta Code right now, so I couldn’t use that reply yet. Please send it again in a moment.");
253491
+ return true;
253492
+ }
253493
+ await this.clear(requestId);
253494
+ if (result === "expired") {
253495
+ await this.options.deliverReprompt(cloneEvent(pending.event), input, "That approval prompt expired before I could use your reply. Please ask the agent to try again.");
253496
+ }
253497
+ return true;
253498
+ }
253499
+ async clear(requestId) {
253500
+ const pending = this.pendingById.get(requestId);
253501
+ if (pending) {
253502
+ this.pendingById.delete(requestId);
253503
+ const scopeKey = getChannelControlRequestScopeKey(pending.event.source);
253504
+ if (this.requestIdByScope.get(scopeKey) === requestId) {
253505
+ this.requestIdByScope.delete(scopeKey);
253506
+ }
253507
+ }
253508
+ await this.options.remove(requestId);
253509
+ }
253510
+ clearAll() {
253511
+ this.pendingById.clear();
253512
+ this.requestIdByScope.clear();
253513
+ }
253514
+ remember(event2, deliveredThisProcess) {
253515
+ const nextEvent = cloneEvent(event2);
253516
+ this.pendingById.set(event2.requestId, {
253517
+ event: nextEvent,
253518
+ deliveredThisProcess
253519
+ });
253520
+ this.requestIdByScope.set(getChannelControlRequestScopeKey(event2.source), event2.requestId);
253521
+ }
253522
+ async deliver(requestId) {
253523
+ const pending = this.pendingById.get(requestId);
253524
+ if (!pending)
253525
+ return false;
253526
+ await this.options.deliverPrompt(cloneEvent(pending.event));
253527
+ pending.deliveredThisProcess = true;
253528
+ return true;
253529
+ }
253530
+ }
253531
+ var init_control_request_coordinator = () => {};
253532
+
253266
253533
  // src/channels/pending-control-requests.ts
253267
253534
  import { existsSync as existsSync38, mkdirSync as mkdirSync27, readFileSync as readFileSync28, writeFileSync as writeFileSync20 } from "node:fs";
253268
253535
  import { dirname as dirname24 } from "node:path";
253269
- function cloneEvent(event2) {
253536
+ function cloneEvent2(event2) {
253270
253537
  return structuredClone(event2);
253271
253538
  }
253272
253539
  function cloneStore(nextStore) {
253273
253540
  return {
253274
- requests: nextStore.requests.map((event2) => cloneEvent(event2))
253541
+ requests: nextStore.requests.map((event2) => cloneEvent2(event2))
253275
253542
  };
253276
253543
  }
253277
253544
  function isChannelControlRequestEvent(value) {
@@ -253300,7 +253567,7 @@ function ensureStoreLoaded() {
253300
253567
  const text2 = readFileSync28(storePath, "utf-8");
253301
253568
  const parsed = JSON.parse(text2);
253302
253569
  store2 = {
253303
- requests: Array.isArray(parsed.requests) ? parsed.requests.filter(isChannelControlRequestEvent).map(cloneEvent) : []
253570
+ requests: Array.isArray(parsed.requests) ? parsed.requests.filter(isChannelControlRequestEvent).map(cloneEvent2) : []
253304
253571
  };
253305
253572
  } catch {
253306
253573
  store2 = EMPTY_STORE();
@@ -253320,11 +253587,11 @@ function saveStore() {
253320
253587
  }
253321
253588
  function listPendingControlRequests() {
253322
253589
  ensureStoreLoaded();
253323
- return store2.requests.map((event2) => cloneEvent(event2));
253590
+ return store2.requests.map((event2) => cloneEvent2(event2));
253324
253591
  }
253325
253592
  function upsertPendingControlRequest(event2) {
253326
253593
  ensureStoreLoaded();
253327
- const nextEvent = cloneEvent(event2);
253594
+ const nextEvent = cloneEvent2(event2);
253328
253595
  const existingIndex = store2.requests.findIndex((candidate) => candidate.requestId === event2.requestId);
253329
253596
  if (existingIndex >= 0) {
253330
253597
  store2.requests[existingIndex] = nextEvent;
@@ -253332,7 +253599,7 @@ function upsertPendingControlRequest(event2) {
253332
253599
  store2.requests.push(nextEvent);
253333
253600
  }
253334
253601
  saveStore();
253335
- return cloneEvent(nextEvent);
253602
+ return cloneEvent2(nextEvent);
253336
253603
  }
253337
253604
  function removePendingControlRequest(requestId) {
253338
253605
  ensureStoreLoaded();
@@ -253351,181 +253618,102 @@ var init_pending_control_requests = __esm(() => {
253351
253618
  });
253352
253619
 
253353
253620
  // src/channels/registry-controls.ts
253354
- function getChannelApprovalScopeKey(params) {
253355
- return [
253356
- params.channel,
253357
- params.accountId ?? LEGACY_CHANNEL_ACCOUNT_ID,
253358
- params.chatId,
253359
- params.threadId ?? ""
253360
- ].join(":");
253361
- }
253362
-
253363
253621
  class ChannelControlRequests {
253364
253622
  deps;
253365
- pendingById = new Map;
253366
- requestIdByScope = new Map;
253623
+ coordinator;
253367
253624
  constructor(deps) {
253368
253625
  this.deps = deps;
253369
- this.primePersistedRequests();
253626
+ this.coordinator = new ChannelControlRequestCoordinator({
253627
+ deliverPrompt: async (event2) => {
253628
+ const adapter = this.getAdapter(event2);
253629
+ if (!adapter)
253630
+ throw new Error("Channel adapter is unavailable");
253631
+ if (adapter.handleControlRequestEvent) {
253632
+ await adapter.handleControlRequestEvent(event2);
253633
+ return;
253634
+ }
253635
+ await adapter.sendDirectReply(event2.source.chatId, formatChannelControlRequestPrompt(event2), { replyToMessageId: event2.source.threadId ?? event2.source.messageId });
253636
+ },
253637
+ deliverReprompt: async (_event, input, message) => {
253638
+ const adapter = this.deps.getAdapter(input.channel, input.accountId ?? LEGACY_CHANNEL_ACCOUNT_ID);
253639
+ if (!adapter)
253640
+ return;
253641
+ await adapter.sendDirectReply(input.chatId, message, buildDirectReplyOptions(input));
253642
+ },
253643
+ deliverResponse: async (event2, response) => {
253644
+ const handler = this.deps.getApprovalResponseHandler();
253645
+ if (!handler)
253646
+ return "unavailable";
253647
+ const handled = await handler({
253648
+ runtime: {
253649
+ agent_id: event2.source.agentId,
253650
+ conversation_id: event2.source.conversationId
253651
+ },
253652
+ response
253653
+ });
253654
+ return handled ? "handled" : "expired";
253655
+ },
253656
+ persist: (event2) => {
253657
+ upsertPendingControlRequest(event2);
253658
+ },
253659
+ remove: (requestId) => {
253660
+ removePendingControlRequest(requestId);
253661
+ }
253662
+ });
253663
+ this.coordinator.restore(listPendingControlRequests());
253370
253664
  }
253371
253665
  has(requestId) {
253372
- return this.pendingById.has(requestId);
253666
+ return this.coordinator.has(requestId);
253373
253667
  }
253374
253668
  getAll() {
253375
- return Array.from(this.pendingById.values()).map((pending) => ({
253376
- event: structuredClone(pending.event),
253377
- deliveredThisProcess: pending.deliveredThisProcess
253378
- }));
253379
- }
253380
- primePersistedRequests() {
253381
- for (const event2 of listPendingControlRequests()) {
253382
- this.pendingById.set(event2.requestId, {
253383
- event: event2,
253384
- deliveredThisProcess: false
253385
- });
253386
- this.requestIdByScope.set(getChannelApprovalScopeKey({
253387
- channel: event2.source.channel,
253388
- accountId: event2.source.accountId,
253389
- chatId: event2.source.chatId,
253390
- threadId: event2.source.threadId
253391
- }), event2.requestId);
253392
- }
253669
+ return this.coordinator.getAll();
253393
253670
  }
253394
253671
  async handleNativeResponse(input) {
253395
- const pending = this.pendingById.get(input.requestId);
253396
- if (!pending)
253397
- return "expired";
253398
- const source2 = pending.event.source;
253399
- const matchesTarget = source2.channel === input.channel && (source2.accountId ?? LEGACY_CHANNEL_ACCOUNT_ID) === (input.accountId ?? LEGACY_CHANNEL_ACCOUNT_ID) && source2.chatId === input.chatId && (source2.threadId ?? null) === (input.threadId ?? null);
253400
- if (!matchesTarget || source2.senderId && source2.senderId !== input.senderId) {
253401
- return "forbidden";
253402
- }
253403
- const approvalResponseHandler = this.deps.getApprovalResponseHandler();
253404
- if (!approvalResponseHandler)
253405
- return "unavailable";
253406
- const handled = await approvalResponseHandler({
253407
- runtime: {
253408
- agent_id: source2.agentId,
253409
- conversation_id: source2.conversationId
253410
- },
253411
- response: input.response
253412
- });
253413
- this.clear(input.requestId);
253414
- return handled ? "handled" : "expired";
253672
+ return this.coordinator.handleNativeResponse(input);
253415
253673
  }
253416
- async deliver(requestId) {
253417
- const pending = this.pendingById.get(requestId);
253418
- if (!pending)
253419
- return false;
253420
- const event2 = pending.event;
253421
- const adapter = this.deps.getAdapter(event2.source.channel, event2.source.accountId ?? LEGACY_CHANNEL_ACCOUNT_ID);
253422
- if (!adapter)
253423
- return false;
253674
+ async register(event2) {
253424
253675
  try {
253425
- if (adapter.handleControlRequestEvent) {
253426
- await adapter.handleControlRequestEvent(event2);
253427
- } else {
253428
- await adapter.sendDirectReply(event2.source.chatId, formatChannelControlRequestPrompt(event2), { replyToMessageId: event2.source.threadId ?? event2.source.messageId });
253429
- }
253430
- pending.deliveredThisProcess = true;
253431
- return true;
253676
+ await this.coordinator.register(event2);
253432
253677
  } catch (error54) {
253433
253678
  console.error(`[Channels] Failed to deliver control request prompt for ${event2.source.channel}/${event2.source.accountId ?? LEGACY_CHANNEL_ACCOUNT_ID}:`, error54 instanceof Error ? error54.message : error54);
253434
- return false;
253435
253679
  }
253436
253680
  }
253437
- async register(event2) {
253438
- const scopeKey = getChannelApprovalScopeKey({
253439
- channel: event2.source.channel,
253440
- accountId: event2.source.accountId,
253441
- chatId: event2.source.chatId,
253442
- threadId: event2.source.threadId
253443
- });
253444
- const existingRequestId = this.requestIdByScope.get(scopeKey);
253445
- if (existingRequestId)
253446
- this.clear(existingRequestId);
253447
- this.pendingById.set(event2.requestId, {
253448
- event: event2,
253449
- deliveredThisProcess: false
253450
- });
253451
- this.requestIdByScope.set(scopeKey, event2.requestId);
253452
- upsertPendingControlRequest(event2);
253453
- await this.deliver(event2.requestId);
253454
- }
253455
253681
  async redeliver(requestId) {
253456
- return this.deliver(requestId);
253682
+ try {
253683
+ return await this.coordinator.redeliver(requestId);
253684
+ } catch (error54) {
253685
+ const pending = this.coordinator.getAll().find((candidate) => candidate.event.requestId === requestId);
253686
+ console.error(`[Channels] Failed to deliver control request prompt for ${pending?.event.source.channel ?? "unknown"}/${pending?.event.source.accountId ?? LEGACY_CHANNEL_ACCOUNT_ID}:`, error54 instanceof Error ? error54.message : error54);
253687
+ return false;
253688
+ }
253457
253689
  }
253458
253690
  clear(requestId) {
253459
- removePendingControlRequest(requestId);
253460
- const pending = this.pendingById.get(requestId);
253461
- if (!pending)
253462
- return;
253463
- this.pendingById.delete(requestId);
253464
- const scopeKey = getChannelApprovalScopeKey({
253465
- channel: pending.event.source.channel,
253466
- accountId: pending.event.source.accountId,
253467
- chatId: pending.event.source.chatId,
253468
- threadId: pending.event.source.threadId
253469
- });
253470
- if (this.requestIdByScope.get(scopeKey) === requestId) {
253471
- this.requestIdByScope.delete(scopeKey);
253472
- }
253691
+ this.coordinator.clear(requestId);
253473
253692
  }
253474
253693
  clearAll() {
253475
- this.pendingById.clear();
253476
- this.requestIdByScope.clear();
253694
+ this.coordinator.clearAll();
253477
253695
  }
253478
- async tryHandleInbound(adapter, msg) {
253696
+ async tryHandleInbound(_adapter, msg) {
253479
253697
  const channelCommand = parseChannelSlashCommand(msg.text) ?? (msg.channel === "slack" && msg.isMention === true ? parseChannelBangCommand(msg.text) : null);
253480
- if (channelCommand)
253481
- return false;
253482
- const scopeKey = getChannelApprovalScopeKey({
253698
+ return this.coordinator.tryHandleInbound({
253483
253699
  channel: msg.channel,
253484
253700
  accountId: msg.accountId,
253485
253701
  chatId: msg.chatId,
253486
- threadId: msg.threadId
253487
- });
253488
- const requestId = this.requestIdByScope.get(scopeKey);
253489
- if (!requestId)
253490
- return false;
253491
- const pending = this.pendingById.get(requestId);
253492
- if (!pending) {
253493
- this.requestIdByScope.delete(scopeKey);
253494
- return false;
253495
- }
253496
- if (pending.event.source.senderId && pending.event.source.senderId !== msg.senderId) {
253497
- return false;
253498
- }
253499
- if (msg.channel === "slack" && pending.event.kind === "generic_tool_approval") {
253500
- return false;
253501
- }
253502
- const parsed = parseChannelControlRequestResponse(pending.event, msg.text);
253503
- if (parsed.type === "reprompt") {
253504
- await adapter.sendDirectReply(msg.chatId, parsed.message, buildDirectReplyOptions(msg));
253505
- return true;
253506
- }
253507
- const approvalResponseHandler = this.deps.getApprovalResponseHandler();
253508
- if (!approvalResponseHandler) {
253509
- await adapter.sendDirectReply(msg.chatId, "I’m reconnecting to Letta Code right now, so I couldn’t use that reply yet. Please send it again in a moment.", buildDirectReplyOptions(msg));
253510
- return true;
253511
- }
253512
- const handled = await approvalResponseHandler({
253513
- runtime: {
253514
- agent_id: pending.event.source.agentId,
253515
- conversation_id: pending.event.source.conversationId
253516
- },
253517
- response: parsed.response
253702
+ messageId: msg.messageId,
253703
+ threadId: msg.threadId,
253704
+ senderId: msg.senderId,
253705
+ text: msg.text,
253706
+ bypass: Boolean(channelCommand)
253518
253707
  });
253519
- this.clear(requestId);
253520
- if (!handled) {
253521
- await adapter.sendDirectReply(msg.chatId, "That approval prompt expired before I could use your reply. Please ask the agent to try again.", buildDirectReplyOptions(msg));
253522
- }
253523
- return true;
253708
+ }
253709
+ getAdapter(event2) {
253710
+ return this.deps.getAdapter(event2.source.channel, event2.source.accountId ?? LEGACY_CHANNEL_ACCOUNT_ID);
253524
253711
  }
253525
253712
  }
253526
253713
  var init_registry_controls = __esm(() => {
253527
253714
  init_accounts();
253528
253715
  init_commands();
253716
+ init_control_request_coordinator();
253529
253717
  init_pending_control_requests();
253530
253718
  init_registry_presentation();
253531
253719
  });
@@ -266897,7 +267085,60 @@ var init_queue = __esm(async () => {
266897
267085
  await init_image_policy();
266898
267086
  });
266899
267087
 
267088
+ // src/websocket/listener/queue-update-outbound.ts
267089
+ function queueEmitScopeKey(scope) {
267090
+ return JSON.stringify([
267091
+ scope?.agent_id ?? null,
267092
+ scope?.conversation_id ?? null
267093
+ ]);
267094
+ }
267095
+ function appendQueueRemovals(target2, removed) {
267096
+ const known = new Set(target2.map((transition) => `${transition.client_message_id}:${transition.disposition}`));
267097
+ for (const transition of removed) {
267098
+ const key2 = `${transition.client_message_id}:${transition.disposition}`;
267099
+ if (known.has(key2))
267100
+ continue;
267101
+ known.add(key2);
267102
+ target2.push(transition);
267103
+ }
267104
+ }
267105
+ function scheduleQueueEmit(runtime, scope, removed = []) {
267106
+ runtime.pendingQueueEmitScope = scope;
267107
+ let pendingByScope = pendingQueueEmitsByRuntime.get(runtime);
267108
+ if (!pendingByScope) {
267109
+ pendingByScope = new Map;
267110
+ pendingQueueEmitsByRuntime.set(runtime, pendingByScope);
267111
+ }
267112
+ const key2 = queueEmitScopeKey(scope);
267113
+ const pending = pendingByScope.get(key2) ?? { scope, removed: [] };
267114
+ appendQueueRemovals(pending.removed, removed);
267115
+ pendingByScope.set(key2, pending);
267116
+ if (runtime.queueEmitScheduled)
267117
+ return;
267118
+ runtime.queueEmitScheduled = true;
267119
+ queueMicrotask(() => {
267120
+ runtime.queueEmitScheduled = false;
267121
+ runtime.pendingQueueEmitScope = undefined;
267122
+ const pendingEmits = pendingQueueEmitsByRuntime.get(runtime);
267123
+ pendingQueueEmitsByRuntime.delete(runtime);
267124
+ for (const pendingEmit of pendingEmits?.values() ?? []) {
267125
+ emitQueueUpdateIfOpen(runtime, pendingEmit.scope, pendingEmit.removed);
267126
+ }
267127
+ });
267128
+ }
267129
+ var pendingQueueEmitsByRuntime;
267130
+ var init_queue_update_outbound = __esm(() => {
267131
+ init_protocol_outbound();
267132
+ pendingQueueEmitsByRuntime = new WeakMap;
267133
+ });
267134
+
266900
267135
  // src/websocket/listener/conversation-runtime.ts
267136
+ function queueRemovalTransition(item, disposition) {
267137
+ return {
267138
+ client_message_id: item.clientMessageId ?? `cm-${item.id}`,
267139
+ disposition
267140
+ };
267141
+ }
266901
267142
  function ensureConversationQueueRuntime(listener, runtime) {
266902
267143
  if (runtime.queueRuntime) {
266903
267144
  return runtime;
@@ -266910,7 +267151,7 @@ function ensureConversationQueueRuntime(listener, runtime) {
266910
267151
  },
266911
267152
  onDequeued: (batch) => {
266912
267153
  runtime.pendingTurns = batch.queueLenAfter;
266913
- scheduleQueueEmit(listener, getQueueItemsScope(batch.items));
267154
+ scheduleQueueEmit(listener, getQueueItemsScope(batch.items), batch.items.map((item) => queueRemovalTransition(item, "dequeued")));
266914
267155
  },
266915
267156
  onBlocked: () => {
266916
267157
  scheduleQueueEmit(listener, {
@@ -266920,13 +267161,23 @@ function ensureConversationQueueRuntime(listener, runtime) {
266920
267161
  },
266921
267162
  onCleared: (_reason, _clearedCount, items3) => {
266922
267163
  runtime.pendingTurns = 0;
266923
- scheduleQueueEmit(listener, getQueueItemsScope(items3));
267164
+ scheduleQueueEmit(listener, getQueueItemsScope(items3), items3.map((item) => queueRemovalTransition(item, "cancelled")));
266924
267165
  evictConversationRuntimeIfIdle(runtime);
266925
267166
  },
266926
267167
  onDropped: (item, _reason, queueLen) => {
266927
267168
  runtime.pendingTurns = queueLen;
266928
267169
  runtime.queuedMessagesByItemId.delete(item.id);
266929
- scheduleQueueEmit(listener, getQueueItemScope(item));
267170
+ scheduleQueueEmit(listener, getQueueItemScope(item), [
267171
+ queueRemovalTransition(item, "cancelled")
267172
+ ]);
267173
+ evictConversationRuntimeIfIdle(runtime);
267174
+ },
267175
+ onRemoved: (item, queueLen) => {
267176
+ runtime.pendingTurns = queueLen;
267177
+ runtime.queuedMessagesByItemId.delete(item.id);
267178
+ scheduleQueueEmit(listener, getQueueItemScope(item), [
267179
+ queueRemovalTransition(item, "cancelled")
267180
+ ]);
266930
267181
  evictConversationRuntimeIfIdle(runtime);
266931
267182
  }
266932
267183
  }
@@ -266938,7 +267189,7 @@ function getOrCreateScopedRuntime(listener, agentId, conversationId) {
266938
267189
  }
266939
267190
  var init_conversation_runtime = __esm(async () => {
266940
267191
  init_queue_runtime();
266941
- init_protocol_outbound();
267192
+ init_queue_update_outbound();
266942
267193
  init_runtime();
266943
267194
  await init_queue();
266944
267195
  });
@@ -267544,8 +267795,9 @@ async function sendEnvironmentMessage(connectionId, body3) {
267544
267795
  async function getEnvironmentConnection(deviceId) {
267545
267796
  return apiRequest("GET", `/v1/environments/${encodeURIComponent(deviceId)}`);
267546
267797
  }
267547
- async function createAgentSandbox(agentId) {
267548
- return apiRequest("POST", `/v1/agents/${encodeURIComponent(agentId)}/sandboxes`, {});
267798
+ async function createAgentSandbox(agentId, options3 = {}, request = apiRequest) {
267799
+ const conversationId = options3.conversationId === "default" ? undefined : options3.conversationId;
267800
+ return request("POST", `/v1/agents/${encodeURIComponent(agentId)}/sandboxes`, conversationId ? { conversationId } : {});
267549
267801
  }
267550
267802
  function isEnvironmentOnline(environment2) {
267551
267803
  return typeof environment2.connectionId === "string" && environment2.connectionId.length > 0 && typeof environment2.lastHeartbeat === "number" && Date.now() - environment2.lastHeartbeat < 120000;
@@ -267585,7 +267837,9 @@ async function resolveEnvironmentConnectionId(selector) {
267585
267837
  async function resolveAgentSandboxConnectionId(agentId, options3 = {}) {
267586
267838
  const timeoutMs = options3.timeoutMs ?? 3 * 60000;
267587
267839
  const pollIntervalMs = options3.pollIntervalMs ?? 2000;
267588
- const sandbox = await createAgentSandbox(agentId);
267840
+ const sandbox = await createAgentSandbox(agentId, {
267841
+ conversationId: options3.conversationId
267842
+ });
267589
267843
  const deviceId = sandbox.deviceId || `sandbox-${agentId}`;
267590
267844
  const deadline = Date.now() + timeoutMs;
267591
267845
  let lastEnvironment = null;
@@ -273202,6 +273456,99 @@ var init_memory_subagent_completion = __esm(() => {
273202
273456
  init_system_prompt_warning();
273203
273457
  });
273204
273458
 
273459
+ // src/backend/api/reflection.ts
273460
+ function agentPath(agentId) {
273461
+ return `/v1/agents/${encodeURIComponent(agentId)}`;
273462
+ }
273463
+ async function updateCloudReflectionConfig(agentId, input, request = apiRequest) {
273464
+ await request("PATCH", `${agentPath(agentId)}/reflection`, { ...input });
273465
+ }
273466
+ async function updateCloudReflectionConversationProgress(agentId, conversationId, input, request = apiRequest) {
273467
+ await request("PATCH", `${agentPath(agentId)}/conversations/${encodeURIComponent(conversationId)}/reflection`, { ...input });
273468
+ }
273469
+ var init_reflection2 = __esm(() => {
273470
+ init_request();
273471
+ });
273472
+
273473
+ // src/cli/helpers/reflection-completion.ts
273474
+ function errorMessage(error54) {
273475
+ return error54 instanceof Error ? error54.message : String(error54);
273476
+ }
273477
+ function logCloudSyncWarning(message) {
273478
+ debugWarn("memory", message);
273479
+ }
273480
+ async function isCloudReflectionAgent() {
273481
+ const backend3 = getBackend();
273482
+ return backend3.capabilities.remoteMemfs && !backend3.capabilities.localMemfs && await isLettaCloud();
273483
+ }
273484
+ async function syncReflectionCompletionToCloud(params, dependencies4 = {}) {
273485
+ const logWarning = dependencies4.logWarning ?? logCloudSyncWarning;
273486
+ try {
273487
+ if (!await (dependencies4.isCloud ?? isCloudReflectionAgent)()) {
273488
+ return;
273489
+ }
273490
+ } catch (error54) {
273491
+ logWarning(`Failed to detect Cloud reflection state: ${errorMessage(error54)}`);
273492
+ return;
273493
+ }
273494
+ let settings3;
273495
+ try {
273496
+ settings3 = (dependencies4.getSettings ?? getReflectionSettings)(params.agentId);
273497
+ } catch (error54) {
273498
+ logWarning(`Failed to resolve Cloud reflection config: ${errorMessage(error54)}`);
273499
+ return;
273500
+ }
273501
+ try {
273502
+ await (dependencies4.updateConfig ?? updateCloudReflectionConfig)(params.agentId, {
273503
+ enabled: settings3.trigger !== "off",
273504
+ min_turn_count: settings3.stepCount
273505
+ });
273506
+ } catch (error54) {
273507
+ logWarning(`Failed to sync Cloud reflection config: ${errorMessage(error54)}`);
273508
+ return;
273509
+ }
273510
+ for (const checkpoint2 of params.checkpoints) {
273511
+ try {
273512
+ await (dependencies4.updateProgress ?? updateCloudReflectionConversationProgress)(params.agentId, checkpoint2.conversationId, {
273513
+ reflected_through_message_id: checkpoint2.reflectedThroughMessageId
273514
+ });
273515
+ } catch (error54) {
273516
+ logWarning(`Failed to sync Cloud reflection progress for ${checkpoint2.conversationId}: ${errorMessage(error54)}`);
273517
+ }
273518
+ }
273519
+ }
273520
+ async function finalizeAutoReflectionCompletion(agentId, conversationId, payloadPath, endSnapshotLine, reflectedThroughMessageId, success2) {
273521
+ await finalizeAutoReflectionPayload(agentId, conversationId, payloadPath, endSnapshotLine, success2);
273522
+ if (!success2) {
273523
+ return;
273524
+ }
273525
+ await syncReflectionCompletionToCloud({
273526
+ agentId,
273527
+ checkpoints: reflectedThroughMessageId ? [{ conversationId, reflectedThroughMessageId }] : []
273528
+ });
273529
+ }
273530
+ async function finalizeMultiReflectionCompletion(agentId, manifest, success2) {
273531
+ await finalizeMultiReflectionPayload(agentId, manifest, success2);
273532
+ if (!success2) {
273533
+ return;
273534
+ }
273535
+ await syncReflectionCompletionToCloud({
273536
+ agentId,
273537
+ checkpoints: manifest.transcripts.filter((slice) => slice.mode === "unreflected").map((slice) => ({
273538
+ conversationId: slice.conversation_id,
273539
+ reflectedThroughMessageId: slice.end_message_id
273540
+ }))
273541
+ });
273542
+ }
273543
+ var init_reflection_completion = __esm(() => {
273544
+ init_memory_filesystem2();
273545
+ init_backend2();
273546
+ init_reflection2();
273547
+ init_memory_reminder();
273548
+ init_reflection_transcript();
273549
+ init_debug();
273550
+ });
273551
+
273205
273552
  // src/cli/helpers/reflection-integration.ts
273206
273553
  function buildReflectionIntegrationConversationTitle(reflectionSubagentId) {
273207
273554
  return reflectionSubagentId ? `Reflection integration (reflection ${reflectionSubagentId})` : "Reflection integration";
@@ -273766,7 +274113,7 @@ async function launchReflectionSubagent(options3) {
273766
274113
  recompileQueuedByConversation,
273767
274114
  logRecompileFailure: (message) => debugWarn("memory", message)
273768
274115
  });
273769
- await finalizeAutoReflectionPayload(agentId, conversationId, autoPayload.payloadPath, autoPayload.endSnapshotLine, completionSuccess);
274116
+ await finalizeAutoReflectionCompletion(agentId, conversationId, autoPayload.payloadPath, autoPayload.endSnapshotLine, autoPayload.endMessageId, completionSuccess);
273770
274117
  await onCompletionMessage?.(completionMessage, {
273771
274118
  success: completionSuccess,
273772
274119
  error: error54,
@@ -273815,6 +274162,7 @@ var init_reflection_launcher = __esm(() => {
273815
274162
  init_backend2();
273816
274163
  init_memory_reminder();
273817
274164
  init_memory_subagent_completion();
274165
+ init_reflection_completion();
273818
274166
  init_reflection_transcript();
273819
274167
  init_telemetry();
273820
274168
  init_reflection_threshold_feedback();
@@ -276319,7 +276667,7 @@ var init_identity2 = __esm(() => {
276319
276667
  function getListenerOAuthDeps() {
276320
276668
  return listenerOAuthDepsOverride ?? defaultListenerOAuthDeps;
276321
276669
  }
276322
- function errorMessage(error54) {
276670
+ function errorMessage2(error54) {
276323
276671
  return error54 instanceof Error ? error54.message : String(error54);
276324
276672
  }
276325
276673
  function getListenerServerUrl(settings3) {
@@ -276402,7 +276750,7 @@ async function resolveListenerAuth(deviceId, connectionName, options3) {
276402
276750
  } catch (refreshError) {
276403
276751
  const retryable = !(refreshError instanceof OAuthRefreshError) || refreshError.retryable;
276404
276752
  if (retryable && isAccessTokenStillValid(settings3, apiKey)) {
276405
- console.warn(`Token refresh failed; using the current access token: ${errorMessage(refreshError)}`);
276753
+ console.warn(`Token refresh failed; using the current access token: ${errorMessage2(refreshError)}`);
276406
276754
  return { serverUrl, apiKey };
276407
276755
  }
276408
276756
  if (retryable) {
@@ -276411,7 +276759,7 @@ async function resolveListenerAuth(deviceId, connectionName, options3) {
276411
276759
  if (!allowInteractiveOAuth) {
276412
276760
  throw new ListenerReauthenticationRequiredError(refreshError);
276413
276761
  }
276414
- console.warn(`Token refresh failed: ${errorMessage(refreshError)}`);
276762
+ console.warn(`Token refresh failed: ${errorMessage2(refreshError)}`);
276415
276763
  apiKey = undefined;
276416
276764
  }
276417
276765
  }
@@ -276466,13 +276814,13 @@ var init_auth = __esm(() => {
276466
276814
  };
276467
276815
  ListenerAuthRetryableError = class ListenerAuthRetryableError extends Error {
276468
276816
  constructor(refreshError) {
276469
- super(`Could not refresh listener credentials: ${errorMessage(refreshError)}`);
276817
+ super(`Could not refresh listener credentials: ${errorMessage2(refreshError)}`);
276470
276818
  this.name = "ListenerAuthRetryableError";
276471
276819
  }
276472
276820
  };
276473
276821
  ListenerReauthenticationRequiredError = class ListenerReauthenticationRequiredError extends Error {
276474
276822
  constructor(refreshError) {
276475
- const detail = refreshError ? `: ${errorMessage(refreshError)}` : "";
276823
+ const detail = refreshError ? `: ${errorMessage2(refreshError)}` : "";
276476
276824
  super(`Saved Letta API credentials require reauthentication${detail}. Run letta to sign in again, or set LETTA_API_KEY.`);
276477
276825
  this.name = "ListenerReauthenticationRequiredError";
276478
276826
  }
@@ -329122,8 +329470,8 @@ ${lanes.join(`
329122
329470
  }
329123
329471
  function resolveExternalModuleName(location, moduleReferenceExpression, ignoreErrors) {
329124
329472
  const isClassic = getEmitModuleResolutionKind(compilerOptions) === 1;
329125
- const errorMessage2 = isClassic ? Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_nodenext_or_to_add_aliases_to_the_paths_option : Diagnostics.Cannot_find_module_0_or_its_corresponding_type_declarations;
329126
- return resolveExternalModuleNameWorker(location, moduleReferenceExpression, ignoreErrors ? undefined : errorMessage2, ignoreErrors);
329473
+ const errorMessage3 = isClassic ? Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_nodenext_or_to_add_aliases_to_the_paths_option : Diagnostics.Cannot_find_module_0_or_its_corresponding_type_declarations;
329474
+ return resolveExternalModuleNameWorker(location, moduleReferenceExpression, ignoreErrors ? undefined : errorMessage3, ignoreErrors);
329127
329475
  }
329128
329476
  function resolveExternalModuleNameWorker(location, moduleReferenceExpression, moduleNotFoundError, ignoreErrors = false, isForAugmentation = false) {
329129
329477
  return isStringLiteralLike(moduleReferenceExpression) ? resolveExternalModule(location, moduleReferenceExpression.text, moduleNotFoundError, !ignoreErrors ? moduleReferenceExpression : undefined, isForAugmentation) : undefined;
@@ -340149,8 +340497,8 @@ ${lanes.join(`
340149
340497
  if (moduleSymbol.flags & targetMeaning) {
340150
340498
  links.resolvedType = resolveImportSymbolType(node, links, moduleSymbol, targetMeaning);
340151
340499
  } else {
340152
- const errorMessage2 = targetMeaning === 111551 ? Diagnostics.Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here : Diagnostics.Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0;
340153
- error210(node, errorMessage2, node.argument.literal.text);
340500
+ const errorMessage3 = targetMeaning === 111551 ? Diagnostics.Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here : Diagnostics.Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0;
340501
+ error210(node, errorMessage3, node.argument.literal.text);
340154
340502
  links.resolvedSymbol = unknownSymbol;
340155
340503
  links.resolvedType = errorType;
340156
340504
  }
@@ -341247,7 +341595,7 @@ ${lanes.join(`
341247
341595
  function elaborateElementwise(iterator2, source2, target2, relation, containingMessageChain, errorOutputContainer) {
341248
341596
  let reportedError = false;
341249
341597
  for (const value of iterator2) {
341250
- const { errorNode: prop, innerExpression: next, nameType, errorMessage: errorMessage2 } = value;
341598
+ const { errorNode: prop, innerExpression: next, nameType, errorMessage: errorMessage3 } = value;
341251
341599
  let targetPropType = getBestMatchIndexedAccessTypeOrUndefined(source2, target2, nameType);
341252
341600
  if (!targetPropType || targetPropType.flags & 8388608)
341253
341601
  continue;
@@ -341270,9 +341618,9 @@ ${lanes.join(`
341270
341618
  const sourceIsOptional = !!(propName && (getPropertyOfType(source2, propName) || unknownSymbol).flags & 16777216);
341271
341619
  targetPropType = removeMissingType(targetPropType, targetIsOptional);
341272
341620
  sourcePropType = removeMissingType(sourcePropType, targetIsOptional && sourceIsOptional);
341273
- const result = checkTypeRelatedTo(specificSource, targetPropType, relation, prop, errorMessage2, containingMessageChain, resultObj);
341621
+ const result = checkTypeRelatedTo(specificSource, targetPropType, relation, prop, errorMessage3, containingMessageChain, resultObj);
341274
341622
  if (result && specificSource !== sourcePropType) {
341275
- checkTypeRelatedTo(sourcePropType, targetPropType, relation, prop, errorMessage2, containingMessageChain, resultObj);
341623
+ checkTypeRelatedTo(sourcePropType, targetPropType, relation, prop, errorMessage3, containingMessageChain, resultObj);
341276
341624
  }
341277
341625
  }
341278
341626
  if (resultObj.errors) {
@@ -341305,7 +341653,7 @@ ${lanes.join(`
341305
341653
  const iterationType = nonTupleOrArrayLikeTargetParts !== neverType2 ? getIterationTypeOfIterable(13, 0, nonTupleOrArrayLikeTargetParts, undefined) : undefined;
341306
341654
  let reportedError = false;
341307
341655
  for (let status = iterator2.next();!status.done; status = iterator2.next()) {
341308
- const { errorNode: prop, innerExpression: next, nameType, errorMessage: errorMessage2 } = status.value;
341656
+ const { errorNode: prop, innerExpression: next, nameType, errorMessage: errorMessage3 } = status.value;
341309
341657
  let targetPropType = iterationType;
341310
341658
  const targetIndexedPropType = tupleOrArrayLikeTargetParts !== neverType2 ? getBestMatchIndexedAccessTypeOrUndefined(source2, tupleOrArrayLikeTargetParts, nameType) : undefined;
341311
341659
  if (targetIndexedPropType && !(targetIndexedPropType.flags & 8388608)) {
@@ -341332,9 +341680,9 @@ ${lanes.join(`
341332
341680
  const sourceIsOptional = !!(propName && (getPropertyOfType(source2, propName) || unknownSymbol).flags & 16777216);
341333
341681
  targetPropType = removeMissingType(targetPropType, targetIsOptional);
341334
341682
  sourcePropType = removeMissingType(sourcePropType, targetIsOptional && sourceIsOptional);
341335
- const result = checkTypeRelatedTo(specificSource, targetPropType, relation, prop, errorMessage2, containingMessageChain, resultObj);
341683
+ const result = checkTypeRelatedTo(specificSource, targetPropType, relation, prop, errorMessage3, containingMessageChain, resultObj);
341336
341684
  if (result && specificSource !== sourcePropType) {
341337
- checkTypeRelatedTo(sourcePropType, targetPropType, relation, prop, errorMessage2, containingMessageChain, resultObj);
341685
+ checkTypeRelatedTo(sourcePropType, targetPropType, relation, prop, errorMessage3, containingMessageChain, resultObj);
341338
341686
  }
341339
341687
  }
341340
341688
  }
@@ -350198,9 +350546,9 @@ ${lanes.join(`
350198
350546
  return;
350199
350547
  }
350200
350548
  const isClassic = getEmitModuleResolutionKind(compilerOptions) === 1;
350201
- const errorMessage2 = isClassic ? Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_nodenext_or_to_add_aliases_to_the_paths_option : Diagnostics.This_JSX_tag_requires_the_module_path_0_to_exist_but_none_could_be_found_Make_sure_you_have_types_for_the_appropriate_package_installed;
350549
+ const errorMessage3 = isClassic ? Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_nodenext_or_to_add_aliases_to_the_paths_option : Diagnostics.This_JSX_tag_requires_the_module_path_0_to_exist_but_none_could_be_found_Make_sure_you_have_types_for_the_appropriate_package_installed;
350202
350550
  const specifier = getJSXRuntimeImportSpecifier(file3, runtimeImportSpecifier);
350203
- const mod = resolveExternalModule(specifier || location, runtimeImportSpecifier, errorMessage2, location);
350551
+ const mod = resolveExternalModule(specifier || location, runtimeImportSpecifier, errorMessage3, location);
350204
350552
  const result = mod && mod !== unknownSymbol ? getMergedSymbol(resolveSymbol(mod)) : undefined;
350205
350553
  if (links) {
350206
350554
  links.jsxImplicitImportContainer = result || false;
@@ -359522,7 +359870,7 @@ ${lanes.join(`
359522
359870
  if (baseDeclarationFlags & 2 || derivedDeclarationFlags & 2) {
359523
359871
  continue;
359524
359872
  }
359525
- let errorMessage2;
359873
+ let errorMessage3;
359526
359874
  const basePropertyFlags = base3.flags & 98308;
359527
359875
  const derivedPropertyFlags = derived.flags & 98308;
359528
359876
  if (basePropertyFlags && derivedPropertyFlags) {
@@ -359551,14 +359899,14 @@ ${lanes.join(`
359551
359899
  continue;
359552
359900
  } else {
359553
359901
  Debug.assert(!!(derived.flags & 98304));
359554
- errorMessage2 = Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor;
359902
+ errorMessage3 = Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor;
359555
359903
  }
359556
359904
  } else if (base3.flags & 98304) {
359557
- errorMessage2 = Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function;
359905
+ errorMessage3 = Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function;
359558
359906
  } else {
359559
- errorMessage2 = Diagnostics.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function;
359907
+ errorMessage3 = Diagnostics.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function;
359560
359908
  }
359561
- error210(getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage2, typeToString(baseType), symbolToString(base3), typeToString(type3));
359909
+ error210(getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage3, typeToString(baseType), symbolToString(base3), typeToString(type3));
359562
359910
  }
359563
359911
  }
359564
359912
  for (const [errorNode, memberInfo] of notImplementedInfo) {
@@ -360404,10 +360752,10 @@ ${lanes.join(`
360404
360752
  }
360405
360753
  return false;
360406
360754
  }
360407
- function checkGrammarModuleElementContext(node, errorMessage2) {
360755
+ function checkGrammarModuleElementContext(node, errorMessage3) {
360408
360756
  const isInAppropriateContext = node.parent.kind === 308 || node.parent.kind === 269 || node.parent.kind === 268;
360409
360757
  if (!isInAppropriateContext) {
360410
- grammarErrorOnFirstToken(node, errorMessage2);
360758
+ grammarErrorOnFirstToken(node, errorMessage3);
360411
360759
  }
360412
360760
  return !isInAppropriateContext;
360413
360761
  }
@@ -386967,14 +387315,14 @@ ${lanes.join(`
386967
387315
  return output;
386968
387316
  }
386969
387317
  function formatDiagnostic2(diagnostic, host) {
386970
- const errorMessage2 = `${diagnosticCategoryName(diagnostic)} TS${diagnostic.code}: ${flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine())}${host.getNewLine()}`;
387318
+ const errorMessage3 = `${diagnosticCategoryName(diagnostic)} TS${diagnostic.code}: ${flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine())}${host.getNewLine()}`;
386971
387319
  if (diagnostic.file) {
386972
387320
  const { line, character } = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
386973
387321
  const fileName = diagnostic.file.fileName;
386974
387322
  const relativeFileName = convertToRelativePath(fileName, host.getCurrentDirectory(), (fileName2) => host.getCanonicalFileName(fileName2));
386975
- return `${relativeFileName}(${line + 1},${character + 1}): ` + errorMessage2;
387323
+ return `${relativeFileName}(${line + 1},${character + 1}): ` + errorMessage3;
386976
387324
  }
386977
- return errorMessage2;
387325
+ return errorMessage3;
386978
387326
  }
386979
387327
  var ForegroundColorEscapeSequences = /* @__PURE__ */ ((ForegroundColorEscapeSequences2) => {
386980
387328
  ForegroundColorEscapeSequences2["Grey"] = "\x1B[90m";
@@ -455052,9 +455400,9 @@ async function drainStream(stream12, buffers, refresh, abortSignal, onFirstMessa
455052
455400
  }
455053
455401
  }
455054
455402
  } catch (e2) {
455055
- const errorMessage2 = e2 instanceof Error ? e2.message : String(e2);
455403
+ const errorMessage3 = e2 instanceof Error ? e2.message : String(e2);
455056
455404
  const sdkDiagnostic = consumeLastSDKDiagnostic();
455057
- const errorMessageWithDiagnostic = sdkDiagnostic ? `${errorMessage2} [${sdkDiagnostic}]` : errorMessage2;
455405
+ const errorMessageWithDiagnostic = sdkDiagnostic ? `${errorMessage3} [${sdkDiagnostic}]` : errorMessage3;
455058
455406
  debugWarn("drainStream", "Stream error caught: %s last_chunk=%s stream=%s", errorMessageWithDiagnostic, lastChunkDebugSummary, summarizeStreamForDebug(stream12));
455059
455407
  if (e2 instanceof Error && e2.stack) {
455060
455408
  debugWarn("drainStream", "Stream error stack: %s", e2.stack);
@@ -461397,10 +461745,10 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
461397
461745
  });
461398
461746
  break;
461399
461747
  }
461400
- const errorMessage2 = errorDetail2 || `Unexpected stop reason: ${stopReason}`;
461748
+ const errorMessage3 = errorDetail2 || `Unexpected stop reason: ${stopReason}`;
461401
461749
  const terminalRunId = runId || runtime.activeRunId || runErrorInfo2?.run_id;
461402
461750
  const noticeParams = {
461403
- message: errorMessage2,
461751
+ message: errorMessage3,
461404
461752
  agentId,
461405
461753
  conversationId,
461406
461754
  runErrorInfo: runErrorInfo2 ?? undefined,
@@ -461423,7 +461771,7 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
461423
461771
  isTerminal: true,
461424
461772
  runId: terminalRunId
461425
461773
  });
461426
- runtime.lastTerminalLoopErrorMessage = formattedError ?? errorMessage2;
461774
+ runtime.lastTerminalLoopErrorMessage = formattedError ?? errorMessage3;
461427
461775
  runtime.lastTerminalLoopErrorRunId = terminalRunId ?? null;
461428
461776
  break;
461429
461777
  }
@@ -461548,10 +461896,10 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
461548
461896
  });
461549
461897
  return;
461550
461898
  }
461551
- const errorMessage2 = error54 instanceof Error ? error54.message : String(error54);
461899
+ const errorMessage3 = error54 instanceof Error ? error54.message : String(error54);
461552
461900
  const terminalRunId = runtime.activeRunId;
461553
461901
  const noticeParams = {
461554
- message: errorMessage2,
461902
+ message: errorMessage3,
461555
461903
  agentId,
461556
461904
  conversationId,
461557
461905
  error: error54,
@@ -461574,7 +461922,7 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
461574
461922
  isTerminal: true,
461575
461923
  runId: terminalRunId
461576
461924
  });
461577
- runtime.lastTerminalLoopErrorMessage = formattedError ?? errorMessage2;
461925
+ runtime.lastTerminalLoopErrorMessage = formattedError ?? errorMessage3;
461578
461926
  runtime.lastTerminalLoopErrorRunId = terminalRunId ?? null;
461579
461927
  if (isDebugEnabled()) {
461580
461928
  console.error("[Listen] Error handling message:", error54);
@@ -464194,16 +464542,16 @@ async function handleExecuteCommand(command, socket, conversationRuntime, opts)
464194
464542
  error: error54,
464195
464543
  context: "listener_command_execution"
464196
464544
  });
464197
- const errorMessage2 = error54 instanceof Error ? error54.message : String(error54);
464545
+ const errorMessage3 = error54 instanceof Error ? error54.message : String(error54);
464198
464546
  emitSlashCommandEnd(socket, conversationRuntime, scope, {
464199
464547
  command_id: command.command_id,
464200
464548
  input,
464201
- output: `Failed: ${errorMessage2}`,
464549
+ output: `Failed: ${errorMessage3}`,
464202
464550
  success: false
464203
464551
  });
464204
464552
  emitExecuteCommandResponse(socket, command, {
464205
464553
  success: false,
464206
- output: `Failed: ${errorMessage2}`
464554
+ output: `Failed: ${errorMessage3}`
464207
464555
  });
464208
464556
  }
464209
464557
  }
@@ -473812,8 +474160,168 @@ var init_mods = __esm(async () => {
473812
474160
  };
473813
474161
  });
473814
474162
 
473815
- // src/cli/subcommands/app-server.ts
474163
+ // src/backend/api/sandbox-files.ts
474164
+ async function throwResponseError(response) {
474165
+ const text2 = await response.text();
474166
+ throw new ApiRequestError(`API error (${response.status}): ${text2}`, response.status, text2);
474167
+ }
474168
+ async function request(path46, init, deps) {
474169
+ const config3 = await deps.getConfig();
474170
+ const headers = new Headers(getLettaCodeHeaders(config3.apiKey));
474171
+ new Headers(init.headers).forEach((value, key2) => {
474172
+ headers.set(key2, value);
474173
+ });
474174
+ if (init.body instanceof FormData) {
474175
+ headers.delete("Content-Type");
474176
+ }
474177
+ const response = await deps.fetch(new URL(path46, config3.baseUrl), {
474178
+ ...init,
474179
+ headers
474180
+ });
474181
+ if (!response.ok)
474182
+ await throwResponseError(response);
474183
+ return response;
474184
+ }
474185
+ async function ensureConversationSandbox(agentId, conversationId, deps = defaultDeps) {
474186
+ const response = await request(`/v1/agents/${encodeURIComponent(agentId)}/sandboxes`, {
474187
+ method: "POST",
474188
+ body: JSON.stringify({ conversationId })
474189
+ }, deps);
474190
+ return await response.json();
474191
+ }
474192
+ async function uploadFileToSandbox(sandboxId, file3, deps = defaultDeps) {
474193
+ const form = new FormData;
474194
+ form.append("file", file3.blob, file3.name);
474195
+ const response = await request(`/v1/sandboxes/${encodeURIComponent(sandboxId)}/files`, {
474196
+ method: "POST",
474197
+ body: form
474198
+ }, deps);
474199
+ return await response.json();
474200
+ }
474201
+ async function downloadFileFromSandbox(sandboxId, path46, deps = defaultDeps) {
474202
+ const query2 = new URLSearchParams({ path: path46 });
474203
+ const response = await request(`/v1/sandboxes/${encodeURIComponent(sandboxId)}/files?${query2}`, { method: "GET" }, deps);
474204
+ return new Uint8Array(await response.arrayBuffer());
474205
+ }
474206
+ var defaultDeps;
474207
+ var init_sandbox_files = __esm(() => {
474208
+ init_http_headers();
474209
+ init_request();
474210
+ defaultDeps = {
474211
+ fetch: globalThis.fetch,
474212
+ getConfig: getApiRequestConfig
474213
+ };
474214
+ });
474215
+
474216
+ // src/cli/subcommands/sandbox.ts
474217
+ import { readFile as readFile25, stat as stat15, writeFile as writeFile18 } from "node:fs/promises";
474218
+ import { basename as basename28, resolve as resolve33 } from "node:path";
473816
474219
  import { parseArgs as parseArgs13 } from "node:util";
474220
+ function printUsage11() {
474221
+ console.log(`
474222
+ Usage:
474223
+ letta sandbox upload <local-path>
474224
+ letta sandbox download <sandbox-path> [--to <local-path>]
474225
+
474226
+ Notes:
474227
+ - Requires an active conversation for a Letta Cloud agent.
474228
+ - Uploads are stored under /root/downloads in the conversation sandbox.
474229
+ - Downloads are limited to files under /root/downloads.
474230
+ - Output is JSON only.
474231
+ `.trim());
474232
+ }
474233
+ function parseSandboxArgs(argv) {
474234
+ return parseArgs13({
474235
+ args: argv,
474236
+ options: SANDBOX_OPTIONS,
474237
+ strict: true,
474238
+ allowPositionals: true
474239
+ });
474240
+ }
474241
+ function getEnvironmentSession(env5) {
474242
+ const agentId = (env5.LETTA_AGENT_ID || env5.AGENT_ID || "").trim();
474243
+ const conversationId = (env5.LETTA_CONVERSATION_ID || env5.CONVERSATION_ID || "").trim();
474244
+ if (!agentId && !conversationId)
474245
+ return null;
474246
+ if (!agentId || !conversationId) {
474247
+ throw new Error("Both agent and conversation context are required when either is set");
474248
+ }
474249
+ return { agentId, conversationId };
474250
+ }
474251
+ function resolveSandboxSession(env5, fallback) {
474252
+ const session = getEnvironmentSession(env5) ?? fallback;
474253
+ if (!session) {
474254
+ throw new Error("No active agent conversation found");
474255
+ }
474256
+ if (isLocalAgentId(session.agentId)) {
474257
+ throw new Error("Sandbox file transfer requires a Letta Cloud agent");
474258
+ }
474259
+ if (!session.conversationId || session.conversationId === "default" || session.conversationId === "new") {
474260
+ throw new Error("Sandbox file transfer requires an active conversation");
474261
+ }
474262
+ return session;
474263
+ }
474264
+ async function runSandboxSubcommand(argv, deps = {}) {
474265
+ let parsed;
474266
+ try {
474267
+ parsed = parseSandboxArgs(argv);
474268
+ } catch (error54) {
474269
+ console.error(`Error: ${error54 instanceof Error ? error54.message : error54}`);
474270
+ printUsage11();
474271
+ return 1;
474272
+ }
474273
+ const [action3, path46] = parsed.positionals;
474274
+ if (parsed.values.help || !action3 || action3 === "help") {
474275
+ printUsage11();
474276
+ return 0;
474277
+ }
474278
+ if (action3 !== "upload" && action3 !== "download" || !path46) {
474279
+ console.error("Error: expected upload or download with a file path");
474280
+ printUsage11();
474281
+ return 1;
474282
+ }
474283
+ try {
474284
+ await (deps.initializeSettings ?? (() => settingsManager.initialize()))();
474285
+ if (!await (deps.isCloud ?? isLettaCloud)()) {
474286
+ throw new Error("Sandbox file transfer is only available on Letta Cloud");
474287
+ }
474288
+ const session = resolveSandboxSession(process.env, (deps.getLastSession ?? (() => settingsManager.getEffectiveLastSession()))());
474289
+ const ensureSandbox = deps.ensureSandbox ?? ensureConversationSandbox;
474290
+ if (action3 === "upload") {
474291
+ const localPath2 = resolve33(path46);
474292
+ const fileStat = await (deps.statLocalPath ?? stat15)(localPath2);
474293
+ if (!fileStat.isFile())
474294
+ throw new Error(`${localPath2} is not a file`);
474295
+ const data2 = await (deps.readLocalFile ?? readFile25)(localPath2);
474296
+ const sandbox2 = await ensureSandbox(session.agentId, session.conversationId);
474297
+ const result = await (deps.uploadFile ?? uploadFileToSandbox)(sandbox2.sandboxId, { blob: new Blob([data2]), name: basename28(localPath2) });
474298
+ console.log(JSON.stringify(result, null, 2));
474299
+ return 0;
474300
+ }
474301
+ const sandbox = await ensureSandbox(session.agentId, session.conversationId);
474302
+ const data = await (deps.downloadFile ?? downloadFileFromSandbox)(sandbox.sandboxId, path46);
474303
+ const localPath = resolve33(parsed.values.to ?? basename28(path46));
474304
+ await (deps.writeLocalFile ?? writeFile18)(localPath, data);
474305
+ console.log(JSON.stringify({ path: localPath, sandboxPath: path46, size: data.byteLength }, null, 2));
474306
+ return 0;
474307
+ } catch (error54) {
474308
+ console.error(`Error: ${error54 instanceof Error ? error54.message : error54}`);
474309
+ return 1;
474310
+ }
474311
+ }
474312
+ var SANDBOX_OPTIONS;
474313
+ var init_sandbox2 = __esm(() => {
474314
+ init_memory_filesystem2();
474315
+ init_sandbox_files();
474316
+ init_settings_manager();
474317
+ SANDBOX_OPTIONS = {
474318
+ help: { type: "boolean", short: "h" },
474319
+ to: { type: "string" }
474320
+ };
474321
+ });
474322
+
474323
+ // src/cli/subcommands/app-server.ts
474324
+ import { parseArgs as parseArgs14 } from "node:util";
473817
474325
  function printAppServerHelp() {
473818
474326
  console.log(`Usage: letta server --listen [url]
473819
474327
 
@@ -473839,7 +474347,7 @@ Examples:
473839
474347
  letta server --listen ws://127.0.0.1:4500 --openai-api`);
473840
474348
  }
473841
474349
  async function waitForShutdown(close) {
473842
- return await new Promise((resolve33) => {
474350
+ return await new Promise((resolve34) => {
473843
474351
  let shuttingDown = false;
473844
474352
  const shutdown = (signal) => {
473845
474353
  if (shuttingDown)
@@ -473848,10 +474356,10 @@ async function waitForShutdown(close) {
473848
474356
  close().then(() => {
473849
474357
  console.log(`
473850
474358
  Stopped App Server (${signal}).`);
473851
- resolve33(0);
474359
+ resolve34(0);
473852
474360
  }).catch((error54) => {
473853
474361
  console.error(error54 instanceof Error ? `Error: ${error54.message}` : String(error54));
473854
- resolve33(1);
474362
+ resolve34(1);
473855
474363
  });
473856
474364
  };
473857
474365
  process.once("SIGINT", shutdown);
@@ -473861,7 +474369,7 @@ Stopped App Server (${signal}).`);
473861
474369
  async function runAppServerSubcommand(argv) {
473862
474370
  let parsed;
473863
474371
  try {
473864
- parsed = parseArgs13({
474372
+ parsed = parseArgs14({
473865
474373
  args: argv,
473866
474374
  allowPositionals: false,
473867
474375
  options: {
@@ -474413,7 +474921,7 @@ __export(exports_setup, {
474413
474921
  runSetup: () => runSetup
474414
474922
  });
474415
474923
  async function runSetup(options3 = {}) {
474416
- return new Promise((resolve33) => {
474924
+ return new Promise((resolve34) => {
474417
474925
  let settled = false;
474418
474926
  let instance2;
474419
474927
  const settle = (result) => {
@@ -474422,7 +474930,7 @@ async function runSetup(options3 = {}) {
474422
474930
  }
474423
474931
  settled = true;
474424
474932
  instance2.unmount();
474425
- resolve33(result);
474933
+ resolve34(result);
474426
474934
  };
474427
474935
  instance2 = render_default(import_react36.default.createElement(SetupUI, {
474428
474936
  initialMode: options3.initialMode,
@@ -474446,7 +474954,7 @@ var init_setup6 = __esm(async () => {
474446
474954
  });
474447
474955
 
474448
474956
  // src/cli/subcommands/setup.ts
474449
- function printUsage11() {
474957
+ function printUsage12() {
474450
474958
  console.log(`
474451
474959
  Usage:
474452
474960
  letta setup
@@ -474457,12 +474965,12 @@ Re-run the interactive setup menu to choose local mode or sign in with Letta.
474457
474965
  async function runSetupSubcommand(argv) {
474458
474966
  const [arg, ...rest3] = argv;
474459
474967
  if (arg === "help" || arg === "--help" || arg === "-h") {
474460
- printUsage11();
474968
+ printUsage12();
474461
474969
  return 0;
474462
474970
  }
474463
474971
  if (arg || rest3.length > 0) {
474464
474972
  console.error(`Unexpected arguments: ${[arg, ...rest3].filter(Boolean).join(" ")}`);
474465
- printUsage11();
474973
+ printUsage12();
474466
474974
  return 1;
474467
474975
  }
474468
474976
  await settingsManager.initialize();
@@ -474477,8 +474985,8 @@ var init_setup7 = __esm(async () => {
474477
474985
  // src/cli/subcommands/shared-memory.ts
474478
474986
  import { existsSync as existsSync57 } from "node:fs";
474479
474987
  import { join as join72 } from "node:path";
474480
- import { parseArgs as parseArgs14 } from "node:util";
474481
- function printUsage12() {
474988
+ import { parseArgs as parseArgs15 } from "node:util";
474989
+ function printUsage13() {
474482
474990
  console.log(`
474483
474991
  Usage:
474484
474992
  letta shared-memory list [--agent <id>]
@@ -474513,7 +475021,7 @@ Examples:
474513
475021
  `.trim());
474514
475022
  }
474515
475023
  function parseSharedMemoryArgs(argv) {
474516
- return parseArgs14({
475024
+ return parseArgs15({
474517
475025
  args: argv,
474518
475026
  options: SHARED_MEMORY_OPTIONS,
474519
475027
  strict: true,
@@ -474529,12 +475037,12 @@ function parseLimit4(value, fallback) {
474529
475037
  const parsed = Number.parseInt(value, 10);
474530
475038
  return Number.isNaN(parsed) || parsed <= 0 ? fallback : parsed;
474531
475039
  }
474532
- async function listOrgRepositories(request) {
475040
+ async function listOrgRepositories(request2) {
474533
475041
  const repositories = [];
474534
475042
  const limit3 = 50;
474535
475043
  let offset = 0;
474536
475044
  for (;; ) {
474537
- const page = await request("GET", `/v1/repositories?limit=${limit3}&offset=${offset}`);
475045
+ const page = await request2("GET", `/v1/repositories?limit=${limit3}&offset=${offset}`);
474538
475046
  repositories.push(...page.repositories);
474539
475047
  if (!page.has_next_page)
474540
475048
  break;
@@ -474542,8 +475050,8 @@ async function listOrgRepositories(request) {
474542
475050
  }
474543
475051
  return repositories;
474544
475052
  }
474545
- async function listAgentRepositories(request, agentId) {
474546
- const response = await request("GET", `/v1/agents/${encodeURIComponent(agentId)}/repositories`);
475053
+ async function listAgentRepositories(request2, agentId) {
475054
+ const response = await request2("GET", `/v1/agents/${encodeURIComponent(agentId)}/repositories`);
474547
475055
  return response.repositories.filter((repository) => !repository.is_primary && repository.name !== "memory");
474548
475056
  }
474549
475057
  function resolveRepositoryReference(repositories, reference) {
@@ -474552,9 +475060,9 @@ function resolveRepositoryReference(repositories, reference) {
474552
475060
  return null;
474553
475061
  return repositories.find((repository) => repository.id === trimmed) ?? repositories.find((repository) => repository.name === trimmed) ?? null;
474554
475062
  }
474555
- async function waitForAttachedRepository(request, agentId, repositoryId, poll) {
475063
+ async function waitForAttachedRepository(request2, agentId, repositoryId, poll) {
474556
475064
  for (let attempt = 0;attempt < poll.attempts; attempt += 1) {
474557
- const attached = await listAgentRepositories(request, agentId);
475065
+ const attached = await listAgentRepositories(request2, agentId);
474558
475066
  if (attached.some((repository) => repository.id === repositoryId)) {
474559
475067
  return true;
474560
475068
  }
@@ -474589,12 +475097,12 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
474589
475097
  parsed = parseSharedMemoryArgs(argv);
474590
475098
  } catch (error54) {
474591
475099
  console.error(error54 instanceof Error ? error54.message : String(error54));
474592
- printUsage12();
475100
+ printUsage13();
474593
475101
  return 1;
474594
475102
  }
474595
475103
  const [action3, reference] = parsed.positionals;
474596
475104
  if (parsed.values.help || !action3 || action3 === "help") {
474597
- printUsage12();
475105
+ printUsage13();
474598
475106
  return 0;
474599
475107
  }
474600
475108
  if (isLocalBackendEnvEnabled()) {
@@ -474602,16 +475110,16 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
474602
475110
  return 1;
474603
475111
  }
474604
475112
  await (deps.initializeSettings ?? (() => settingsManager.initialize()))();
474605
- const request = deps.request ?? apiRequest;
475113
+ const request2 = deps.request ?? apiRequest;
474606
475114
  const syncRepositories = deps.syncRepositories ?? syncAttachedAgentRepositories;
474607
475115
  const recompileAgent = deps.recompileAgent ?? defaultRecompileAgent;
474608
475116
  try {
474609
475117
  if (action3 === "list") {
474610
475118
  const agentId = resolveSharedMemoryAgentId(parsed.values.agent, parsed.values["agent-id"]);
474611
- const repositories = await listOrgRepositories(request);
475119
+ const repositories = await listOrgRepositories(request2);
474612
475120
  let attachedIds = new Set;
474613
475121
  if (agentId && !isLocalAgentId(agentId)) {
474614
- const attached = await listAgentRepositories(request, agentId);
475122
+ const attached = await listAgentRepositories(request2, agentId);
474615
475123
  attachedIds = new Set(attached.map((repository) => repository.id));
474616
475124
  }
474617
475125
  console.log(JSON.stringify({
@@ -474628,7 +475136,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
474628
475136
  console.error("Usage: letta shared-memory create --name <name>");
474629
475137
  return 1;
474630
475138
  }
474631
- const repository = await request("POST", "/v1/repositories", { name });
475139
+ const repository = await request2("POST", "/v1/repositories", { name });
474632
475140
  console.log(JSON.stringify(repository, null, 2));
474633
475141
  return 0;
474634
475142
  }
@@ -474637,7 +475145,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
474637
475145
  console.error(`Usage: letta shared-memory ${action3} <name-or-id>`);
474638
475146
  return 1;
474639
475147
  }
474640
- const repositories = await listOrgRepositories(request);
475148
+ const repositories = await listOrgRepositories(request2);
474641
475149
  const repository = resolveRepositoryReference(repositories, reference);
474642
475150
  if (!repository) {
474643
475151
  console.error(`Repository not found: ${reference}. Run \`letta shared-memory list\` to see available repositories.`);
@@ -474649,7 +475157,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
474649
475157
  if (parsed.values.path) {
474650
475158
  query2.set("path", parsed.values.path);
474651
475159
  }
474652
- const versions2 = await request("GET", `/v1/repositories/${encodeURIComponent(repository.id)}/versions?${query2}`);
475160
+ const versions2 = await request2("GET", `/v1/repositories/${encodeURIComponent(repository.id)}/versions?${query2}`);
474653
475161
  console.log(JSON.stringify({ repository: repository.name, ...versions2 }, null, 2));
474654
475162
  return 0;
474655
475163
  }
@@ -474657,8 +475165,8 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
474657
475165
  if (!agentId)
474658
475166
  return 1;
474659
475167
  if (action3 === "attach") {
474660
- await request("POST", `/v1/agents/${encodeURIComponent(agentId)}/repositories`, { repository_id: repository.id });
474661
- const visible = await waitForAttachedRepository(request, agentId, repository.id, deps.attachPoll ?? DEFAULT_ATTACH_POLL);
475168
+ await request2("POST", `/v1/agents/${encodeURIComponent(agentId)}/repositories`, { repository_id: repository.id });
475169
+ const visible = await waitForAttachedRepository(request2, agentId, repository.id, deps.attachPoll ?? DEFAULT_ATTACH_POLL);
474662
475170
  if (!visible) {
474663
475171
  console.error(`Attach accepted but ${repository.name} did not appear in the agent's repository list. Retry \`letta shared-memory sync\` shortly.`);
474664
475172
  return 1;
@@ -474677,7 +475185,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
474677
475185
  }, null, 2));
474678
475186
  return mounted ? 0 : 1;
474679
475187
  }
474680
- await request("DELETE", `/v1/agents/${encodeURIComponent(agentId)}/repositories/${encodeURIComponent(repository.id)}`);
475188
+ await request2("DELETE", `/v1/agents/${encodeURIComponent(agentId)}/repositories/${encodeURIComponent(repository.id)}`);
474681
475189
  const detachRecompileError = await recompileAndReportFailure(recompileAgent, agentId);
474682
475190
  console.log(JSON.stringify({
474683
475191
  detached: true,
@@ -474696,7 +475204,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
474696
475204
  return result.failed > 0 ? 1 : 0;
474697
475205
  }
474698
475206
  console.error(`Unknown action: ${action3}`);
474699
- printUsage12();
475207
+ printUsage13();
474700
475208
  return 1;
474701
475209
  } catch (error54) {
474702
475210
  console.error(error54 instanceof Error ? error54.message : String(error54));
@@ -476202,9 +476710,9 @@ import {
476202
476710
  } from "node:fs";
476203
476711
  import { mkdir as mkdir15, readdir as readdir14 } from "node:fs/promises";
476204
476712
  import { tmpdir as tmpdir10 } from "node:os";
476205
- import { basename as basename28, dirname as dirname33, join as join73, normalize as normalize5, resolve as resolve33, sep as sep7 } from "node:path";
476206
- import { parseArgs as parseArgs15, TextDecoder as TextDecoder2, TextEncoder as TextEncoder2 } from "node:util";
476207
- function printUsage13() {
476713
+ import { basename as basename29, dirname as dirname33, join as join73, normalize as normalize5, resolve as resolve34, sep as sep7 } from "node:path";
476714
+ import { parseArgs as parseArgs16, TextDecoder as TextDecoder2, TextEncoder as TextEncoder2 } from "node:util";
476715
+ function printUsage14() {
476208
476716
  console.log(`
476209
476717
  Usage:
476210
476718
  letta install <thing> [--agent <id> | -n <agent name>] [--force]
@@ -476231,7 +476739,7 @@ Options:
476231
476739
  `.trim());
476232
476740
  }
476233
476741
  function parseSkillsArgs(argv) {
476234
- return parseArgs15({
476742
+ return parseArgs16({
476235
476743
  args: argv,
476236
476744
  options: SKILLS_OPTIONS,
476237
476745
  strict: true,
@@ -476397,7 +476905,7 @@ function parseDirectSkillFileUrlSpecifier(input) {
476397
476905
  if (url2.protocol !== "https:" && !(url2.protocol === "http:" && isLocalhostHostname(url2.hostname))) {
476398
476906
  return null;
476399
476907
  }
476400
- if (basename28(url2.pathname).toLowerCase() !== "skill.md")
476908
+ if (basename29(url2.pathname).toLowerCase() !== "skill.md")
476401
476909
  return null;
476402
476910
  return { url: url2.toString() };
476403
476911
  }
@@ -476628,8 +477136,8 @@ async function downloadClawHubSkillSource(location) {
476628
477136
  return { tmpDir, sourceDir };
476629
477137
  }
476630
477138
  function assertInside(parent, child) {
476631
- const parentPath = resolve33(parent);
476632
- const childPath = resolve33(child);
477139
+ const parentPath = resolve34(parent);
477140
+ const childPath = resolve34(child);
476633
477141
  if (childPath !== parentPath && !childPath.startsWith(`${parentPath}${sep7}`)) {
476634
477142
  throw new Error(`Resolved path is outside target directory: ${child}`);
476635
477143
  }
@@ -476645,12 +477153,12 @@ function getSkillName(sourceDir) {
476645
477153
  const skillMd = readFileSync39(join73(sourceDir, "SKILL.md"), "utf8");
476646
477154
  const { frontmatter } = parseFrontmatter(skillMd);
476647
477155
  const frontmatterName = frontmatter.name;
476648
- const name = typeof frontmatterName === "string" && frontmatterName.trim() ? frontmatterName : basename28(sourceDir);
477156
+ const name = typeof frontmatterName === "string" && frontmatterName.trim() ? frontmatterName : basename29(sourceDir);
476649
477157
  return sanitizeSkillName(name);
476650
477158
  }
476651
477159
  async function installSkillDirectory(params) {
476652
- const sourceDir = resolve33(params.sourceDir);
476653
- const memoryDir = resolve33(params.memoryDir);
477160
+ const sourceDir = resolve34(params.sourceDir);
477161
+ const memoryDir = resolve34(params.memoryDir);
476654
477162
  const skillMdPath = join73(sourceDir, "SKILL.md");
476655
477163
  if (!existsSync58(skillMdPath)) {
476656
477164
  throw new Error("No SKILL.md found in the skill directory.");
@@ -476671,12 +477179,12 @@ async function installSkillDirectory(params) {
476671
477179
  await mkdir15(skillsDir, { recursive: true });
476672
477180
  cpSync2(sourceDir, targetPath, {
476673
477181
  recursive: true,
476674
- filter: (source2) => basename28(source2) !== ".git"
477182
+ filter: (source2) => basename29(source2) !== ".git"
476675
477183
  });
476676
477184
  return { name, path: normalize5(targetPath) };
476677
477185
  }
476678
477186
  async function listSkillDirectories(params) {
476679
- const memoryDir = resolve33(params.memoryDir);
477187
+ const memoryDir = resolve34(params.memoryDir);
476680
477188
  const skillsDir = join73(memoryDir, "skills");
476681
477189
  if (!existsSync58(skillsDir))
476682
477190
  return [];
@@ -476706,7 +477214,7 @@ async function listSkillDirectories(params) {
476706
477214
  return skills.sort((a2, b3) => a2.name.localeCompare(b3.name));
476707
477215
  }
476708
477216
  async function deleteSkillDirectory(params) {
476709
- const memoryDir = resolve33(params.memoryDir);
477217
+ const memoryDir = resolve34(params.memoryDir);
476710
477218
  const skillsDir = join73(memoryDir, "skills");
476711
477219
  const name = sanitizeSkillName(params.name);
476712
477220
  const targetPath = join73(skillsDir, name);
@@ -476758,7 +477266,7 @@ async function installSkill(specifier, agentId, force) {
476758
477266
  downloaded = await downloadClawHubSkillSource(source2.location);
476759
477267
  }
476760
477268
  tmpDir = downloaded.tmpDir;
476761
- const sourceDir = resolve33(downloaded.sourceDir);
477269
+ const sourceDir = resolve34(downloaded.sourceDir);
476762
477270
  assertInside(tmpDir, sourceDir);
476763
477271
  if (!existsSync58(sourceDir)) {
476764
477272
  const missingPath = source2.type === "git" ? source2.location.subdir ?? "." : source2.type === "direct-file" ? source2.location.url : source2.location.slug;
@@ -476879,17 +477387,17 @@ async function runInstall(argv, options3 = {}) {
476879
477387
  parsed = parseSkillsArgs(argv);
476880
477388
  } catch (error54) {
476881
477389
  console.error(`Error: ${error54 instanceof Error ? error54.message : String(error54)}`);
476882
- printUsage13();
477390
+ printUsage14();
476883
477391
  return 1;
476884
477392
  }
476885
477393
  const [specifier] = parsed.positionals;
476886
477394
  if (parsed.values.help || !specifier || specifier === "help") {
476887
- printUsage13();
477395
+ printUsage14();
476888
477396
  return 0;
476889
477397
  }
476890
477398
  if (parsed.positionals.length > 1) {
476891
477399
  console.error(`Unexpected argument: ${parsed.positionals[1]}`);
476892
- printUsage13();
477400
+ printUsage14();
476893
477401
  return 1;
476894
477402
  }
476895
477403
  if (specifier.startsWith("npm:")) {
@@ -476941,7 +477449,7 @@ async function runInstall(argv, options3 = {}) {
476941
477449
  return 1;
476942
477450
  }
476943
477451
  }
476944
- const maybeLocalPath = resolve33(specifier);
477452
+ const maybeLocalPath = resolve34(specifier);
476945
477453
  if (isLocalLettaModPackageDirectory(maybeLocalPath)) {
476946
477454
  if (hasInstallAgentScope(parsed.values)) {
476947
477455
  console.error("Agent-scoped mod package install is not supported yet.");
@@ -476980,16 +477488,16 @@ async function runList2(argv) {
476980
477488
  parsed = parseSkillsArgs(argv);
476981
477489
  } catch (error54) {
476982
477490
  console.error(`Error: ${error54 instanceof Error ? error54.message : String(error54)}`);
476983
- printUsage13();
477491
+ printUsage14();
476984
477492
  return 1;
476985
477493
  }
476986
477494
  if (parsed.values.help) {
476987
- printUsage13();
477495
+ printUsage14();
476988
477496
  return 0;
476989
477497
  }
476990
477498
  if (parsed.positionals.length > 0) {
476991
477499
  console.error(`Unexpected argument: ${parsed.positionals[0]}`);
476992
- printUsage13();
477500
+ printUsage14();
476993
477501
  return 1;
476994
477502
  }
476995
477503
  try {
@@ -477010,17 +477518,17 @@ async function runDelete(argv) {
477010
477518
  parsed = parseSkillsArgs(argv);
477011
477519
  } catch (error54) {
477012
477520
  console.error(`Error: ${error54 instanceof Error ? error54.message : String(error54)}`);
477013
- printUsage13();
477521
+ printUsage14();
477014
477522
  return 1;
477015
477523
  }
477016
477524
  const [skillName] = parsed.positionals;
477017
477525
  if (parsed.values.help || !skillName || skillName === "help") {
477018
- printUsage13();
477526
+ printUsage14();
477019
477527
  return 0;
477020
477528
  }
477021
477529
  if (parsed.positionals.length > 1) {
477022
477530
  console.error(`Unexpected argument: ${parsed.positionals[1]}`);
477023
- printUsage13();
477531
+ printUsage14();
477024
477532
  return 1;
477025
477533
  }
477026
477534
  const agentId = getExplicitAgentId2(parsed.values);
@@ -477060,11 +477568,11 @@ async function runSkillsSubcommand(argv) {
477060
477568
  case "help":
477061
477569
  case "--help":
477062
477570
  case "-h":
477063
- printUsage13();
477571
+ printUsage14();
477064
477572
  return 0;
477065
477573
  default:
477066
477574
  console.error(`Unknown action: ${action3}`);
477067
- printUsage13();
477575
+ printUsage14();
477068
477576
  return 1;
477069
477577
  }
477070
477578
  }
@@ -477083,26 +477591,26 @@ var init_skills4 = __esm(() => {
477083
477591
  });
477084
477592
 
477085
477593
  // src/cli/subcommands/trajectories/readers.ts
477086
- import { readdir as readdir15, readFile as readFile25, stat as stat15 } from "node:fs/promises";
477594
+ import { readdir as readdir15, readFile as readFile26, stat as stat16 } from "node:fs/promises";
477087
477595
  import { join as join74 } from "node:path";
477088
477596
  async function loadSessionTranscript(item) {
477089
- const stats = await stat15(item.path);
477597
+ const stats = await stat16(item.path);
477090
477598
  if (stats.isDirectory()) {
477091
477599
  return assembleEventDirectory(item.path);
477092
477600
  }
477093
477601
  if (item.path.endsWith(".db")) {
477094
477602
  return exportHermesSession(item.path, item.id);
477095
477603
  }
477096
- return readFile25(item.path, "utf-8");
477604
+ return readFile26(item.path, "utf-8");
477097
477605
  }
477098
477606
  async function assembleEventDirectory(sessionDir) {
477099
477607
  const eventsSubdir = join74(sessionDir, "events");
477100
- const eventsDir = (await stat15(eventsSubdir).catch(() => null))?.isDirectory() ? eventsSubdir : sessionDir;
477608
+ const eventsDir = (await stat16(eventsSubdir).catch(() => null))?.isDirectory() ? eventsSubdir : sessionDir;
477101
477609
  const names = (await readdir15(eventsDir, { withFileTypes: true })).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a2, b3) => Number.parseInt(a2, 10) - Number.parseInt(b3, 10) || a2.localeCompare(b3));
477102
477610
  if (names.length === 0) {
477103
477611
  throw new Error(`No event files found in ${eventsDir}`);
477104
477612
  }
477105
- const events = await Promise.all(names.map(async (name) => JSON.parse(await readFile25(join74(eventsDir, name), "utf-8"))));
477613
+ const events = await Promise.all(names.map(async (name) => JSON.parse(await readFile26(join74(eventsDir, name), "utf-8"))));
477106
477614
  return JSON.stringify(events);
477107
477615
  }
477108
477616
  async function openReadOnlyDatabase(path46) {
@@ -477175,12 +477683,12 @@ import { createHash as createHash12 } from "node:crypto";
477175
477683
  import {
477176
477684
  mkdir as mkdir16,
477177
477685
  readdir as readdir16,
477178
- readFile as readFile26,
477686
+ readFile as readFile27,
477179
477687
  rm as rm10,
477180
- stat as stat16,
477181
- writeFile as writeFile18
477688
+ stat as stat17,
477689
+ writeFile as writeFile19
477182
477690
  } from "node:fs/promises";
477183
- import { basename as basename29, join as join75 } from "node:path";
477691
+ import { basename as basename30, join as join75 } from "node:path";
477184
477692
  function fileTimestamp(startedAt) {
477185
477693
  if (!startedAt)
477186
477694
  return "unknown-date";
@@ -477241,7 +477749,7 @@ function collectStats(records) {
477241
477749
  }
477242
477750
  async function prepareOutDir(outDir) {
477243
477751
  try {
477244
- const existing = await stat16(outDir);
477752
+ const existing = await stat17(outDir);
477245
477753
  if (!existing.isDirectory()) {
477246
477754
  throw new Error(`--out ${outDir} exists and is not a directory`);
477247
477755
  }
@@ -477300,7 +477808,7 @@ async function runTrajectoryExport(options3) {
477300
477808
  usedFiles.add(file3);
477301
477809
  const body3 = JSON.stringify(records);
477302
477810
  await mkdir16(join75(options3.outDir, source2), { recursive: true });
477303
- await writeFile18(join75(options3.outDir, file3), body3, "utf-8");
477811
+ await writeFile19(join75(options3.outDir, file3), body3, "utf-8");
477304
477812
  counts.exported += 1;
477305
477813
  manifest2.sessions.push({
477306
477814
  source: source2,
@@ -477348,13 +477856,13 @@ async function runTrajectoryExport(options3) {
477348
477856
  if (!supported.includes(explicit.source)) {
477349
477857
  throw new Error(`Unknown source "${explicit.source}" in --transcript. The installed trajectory package supports: ${supported.join(", ")}.`);
477350
477858
  }
477351
- await exportTranscript(explicit.source, basename29(explicit.path).replace(/\.[^.]+$/, ""), explicit.path, () => readFile26(explicit.path, "utf-8"));
477859
+ await exportTranscript(explicit.source, basename30(explicit.path).replace(/\.[^.]+$/, ""), explicit.path, () => readFile27(explicit.path, "utf-8"));
477352
477860
  }
477353
477861
  for (const checkpoint2 of options3.deepagents ?? []) {
477354
- await exportCheckpoint(checkpoint2, `${basename29(checkpoint2.path)}-${checkpoint2.threadId}`);
477862
+ await exportCheckpoint(checkpoint2, `${basename30(checkpoint2.path)}-${checkpoint2.threadId}`);
477355
477863
  }
477356
477864
  manifest2.sessions.sort((a2, b3) => (a2.startedAt ?? "").localeCompare(b3.startedAt ?? ""));
477357
- await writeFile18(join75(options3.outDir, MANIFEST_NAME), JSON.stringify(manifest2, null, 2), "utf-8");
477865
+ await writeFile19(join75(options3.outDir, MANIFEST_NAME), JSON.stringify(manifest2, null, 2), "utf-8");
477358
477866
  return manifest2;
477359
477867
  }
477360
477868
  var MANIFEST_NAME = "manifest.json", FIRST_PROMPT_MAX_CHARS = 200, LIST_PAGE_LIMIT = 1000;
@@ -477365,12 +477873,12 @@ var init_export = __esm(() => {
477365
477873
  });
477366
477874
 
477367
477875
  // src/cli/subcommands/trajectories/review.ts
477368
- import { readFile as readFile27 } from "node:fs/promises";
477876
+ import { readFile as readFile28 } from "node:fs/promises";
477369
477877
  import { isAbsolute as isAbsolute27, join as join76 } from "node:path";
477370
477878
  async function readManifest(dir) {
477371
477879
  let raw2;
477372
477880
  try {
477373
- raw2 = await readFile27(join76(dir, "manifest.json"), "utf-8");
477881
+ raw2 = await readFile28(join76(dir, "manifest.json"), "utf-8");
477374
477882
  } catch {
477375
477883
  throw new Error(`No manifest at ${join76(dir, "manifest.json")}. Run: letta trajectories export --out ${dir}`);
477376
477884
  }
@@ -477383,7 +477891,7 @@ async function resolveSessionFile(dir, target2) {
477383
477891
  if (target2.endsWith(".json")) {
477384
477892
  const direct = isAbsolute27(target2) ? target2 : join76(dir, target2);
477385
477893
  try {
477386
- await readFile27(direct, "utf-8");
477894
+ await readFile28(direct, "utf-8");
477387
477895
  return direct;
477388
477896
  } catch {}
477389
477897
  }
@@ -477435,7 +477943,7 @@ async function searchSessions(dir, keyword, options3 = {}) {
477435
477943
  for (const session of filterSessions(manifest2.sessions, options3)) {
477436
477944
  let records;
477437
477945
  try {
477438
- records = JSON.parse(await readFile27(join76(dir, session.file), "utf-8"));
477946
+ records = JSON.parse(await readFile28(join76(dir, session.file), "utf-8"));
477439
477947
  } catch {
477440
477948
  continue;
477441
477949
  }
@@ -477466,9 +477974,9 @@ var TOOL_RESULT_MAX_CHARS = 500, REASONING_MAX_CHARS = 300, TOOL_ARGS_MAX_CHARS
477466
477974
  var init_review = () => {};
477467
477975
 
477468
477976
  // src/cli/subcommands/trajectories.ts
477469
- import { readFile as readFile28 } from "node:fs/promises";
477470
- import { parseArgs as parseArgs16 } from "node:util";
477471
- function printUsage14() {
477977
+ import { readFile as readFile29 } from "node:fs/promises";
477978
+ import { parseArgs as parseArgs17 } from "node:util";
477979
+ function printUsage15() {
477472
477980
  console.log(`
477473
477981
  Usage:
477474
477982
  letta trajectories export [options]
@@ -477573,7 +478081,7 @@ async function runView(flags, target2, options3) {
477573
478081
  return 1;
477574
478082
  }
477575
478083
  const path46 = await resolveSessionFile(flags.dir, target2);
477576
- const records = JSON.parse(await readFile28(path46, "utf-8"));
478084
+ const records = JSON.parse(await readFile29(path46, "utf-8"));
477577
478085
  console.log(renderSession(records, options3));
477578
478086
  return 0;
477579
478087
  }
@@ -477606,7 +478114,7 @@ ${results.length} session(s) matched "${keyword}"`);
477606
478114
  return 0;
477607
478115
  }
477608
478116
  function parseTrajectoriesArgs(argv) {
477609
- return parseArgs16({
478117
+ return parseArgs17({
477610
478118
  args: argv,
477611
478119
  options: TRAJECTORIES_OPTIONS,
477612
478120
  strict: true,
@@ -477619,12 +478127,12 @@ async function runTrajectoriesSubcommand(argv) {
477619
478127
  parsed = parseTrajectoriesArgs(argv);
477620
478128
  } catch (error54) {
477621
478129
  console.error(`Error: ${error54 instanceof Error ? error54.message : String(error54)}`);
477622
- printUsage14();
478130
+ printUsage15();
477623
478131
  return 1;
477624
478132
  }
477625
478133
  const [action3] = parsed.positionals;
477626
478134
  if (parsed.values.help || action3 === "help" || !action3) {
477627
- printUsage14();
478135
+ printUsage15();
477628
478136
  return parsed.values.help || action3 === "help" ? 0 : 1;
477629
478137
  }
477630
478138
  const asJson = Boolean(parsed.values.json);
@@ -477656,7 +478164,7 @@ async function runTrajectoriesSubcommand(argv) {
477656
478164
  }
477657
478165
  if (action3 !== "export") {
477658
478166
  console.error(`Unknown command: ${action3}`);
477659
- printUsage14();
478167
+ printUsage15();
477660
478168
  return 1;
477661
478169
  }
477662
478170
  const options3 = {
@@ -477799,7 +478307,7 @@ function waitForSocketOpen(socket) {
477799
478307
  if (socket.readyState === WEBSOCKET_OPEN_STATE) {
477800
478308
  return Promise.resolve();
477801
478309
  }
477802
- return new Promise((resolve34, reject) => {
478310
+ return new Promise((resolve35, reject) => {
477803
478311
  let detachOpen = () => {};
477804
478312
  let detachError = () => {};
477805
478313
  const cleanup = () => {
@@ -477808,7 +478316,7 @@ function waitForSocketOpen(socket) {
477808
478316
  };
477809
478317
  detachOpen = onceSocketEvent(socket, "open", () => {
477810
478318
  cleanup();
477811
- resolve34();
478319
+ resolve35();
477812
478320
  });
477813
478321
  detachError = onceSocketEvent(socket, "error", (event2) => {
477814
478322
  cleanup();
@@ -477921,13 +478429,13 @@ class AppServerClient {
477921
478429
  }
477922
478430
  requestRaw(command, options3) {
477923
478431
  const timeoutMs = options3.timeoutMs ?? this.requestTimeoutMs;
477924
- return new Promise((resolve34, reject) => {
478432
+ return new Promise((resolve35, reject) => {
477925
478433
  const timeout = setTimeout(() => {
477926
478434
  this.pending.delete(command.request_id);
477927
478435
  reject(new Error(`Timed out waiting for ${command.request_id}`));
477928
478436
  }, timeoutMs);
477929
478437
  this.pending.set(command.request_id, {
477930
- resolve: (message) => resolve34(message),
478438
+ resolve: (message) => resolve35(message),
477931
478439
  reject,
477932
478440
  predicate: options3.predicate,
477933
478441
  timeout
@@ -477950,13 +478458,13 @@ class AppServerClient {
477950
478458
  } : commandOrType;
477951
478459
  const options3 = isTypeRequest ? maybeOptions : bodyOrOptions;
477952
478460
  const timeoutMs = options3.timeoutMs ?? this.requestTimeoutMs;
477953
- return new Promise((resolve34, reject) => {
478461
+ return new Promise((resolve35, reject) => {
477954
478462
  const timeout = setTimeout(() => {
477955
478463
  this.pending.delete(command.request_id);
477956
478464
  reject(new Error(`Timed out waiting for ${command.request_id}`));
477957
478465
  }, timeoutMs);
477958
478466
  this.pending.set(command.request_id, {
477959
- resolve: (message) => resolve34(message),
478467
+ resolve: (message) => resolve35(message),
477960
478468
  reject,
477961
478469
  predicate: options3.predicate,
477962
478470
  timeout
@@ -478825,44 +479333,44 @@ function trimmedOrNull(value) {
478825
479333
  const trimmed = value?.trim();
478826
479334
  return trimmed ? trimmed : null;
478827
479335
  }
478828
- function effectiveTextThreadId(request, route) {
478829
- const requestThreadId = trimmedOrNull(request.threadId);
479336
+ function effectiveTextThreadId(request2, route) {
479337
+ const requestThreadId = trimmedOrNull(request2.threadId);
478830
479338
  const routeThreadId = trimmedOrNull(route.threadId);
478831
- if (request.channel === "telegram") {
479339
+ if (request2.channel === "telegram") {
478832
479340
  if (requestThreadId)
478833
479341
  return requestThreadId;
478834
479342
  if (route.chatType === "direct")
478835
479343
  return null;
478836
479344
  return route.chatId.trim().startsWith("-") ? routeThreadId : null;
478837
479345
  }
478838
- if (request.channel === "discord") {
479346
+ if (request2.channel === "discord") {
478839
479347
  return route.chatType === "direct" ? route.chatId : requestThreadId ?? routeThreadId;
478840
479348
  }
478841
- if (request.channel === "slack") {
478842
- const isDirect = route.chatType === "direct" || request.chatId.startsWith("D");
479349
+ if (request2.channel === "slack") {
479350
+ const isDirect = route.chatType === "direct" || request2.chatId.startsWith("D");
478843
479351
  if (isDirect)
478844
479352
  return requestThreadId ?? routeThreadId;
478845
- return request.replyToMessageId ? null : requestThreadId ?? routeThreadId;
479353
+ return request2.replyToMessageId ? null : requestThreadId ?? routeThreadId;
478846
479354
  }
478847
479355
  return null;
478848
479356
  }
478849
- function effectiveTextReplyId(request, route) {
478850
- const isSlackDirect = request.channel === "slack" && (route.chatType === "direct" || request.chatId.startsWith("D"));
478851
- return isSlackDirect ? null : trimmedOrNull(request.replyToMessageId);
479357
+ function effectiveTextReplyId(request2, route) {
479358
+ const isSlackDirect = request2.channel === "slack" && (route.chatType === "direct" || request2.chatId.startsWith("D"));
479359
+ return isSlackDirect ? null : trimmedOrNull(request2.replyToMessageId);
478852
479360
  }
478853
- function messageIdempotencyKey(request, route) {
478854
- if (request.action !== "send" && request.action !== "send-rich" || request.mediaPath) {
479361
+ function messageIdempotencyKey(request2, route) {
479362
+ if (request2.action !== "send" && request2.action !== "send-rich" || request2.mediaPath) {
478855
479363
  return null;
478856
479364
  }
478857
479365
  return JSON.stringify({
478858
- action: request.action,
478859
- channel: request.channel,
479366
+ action: request2.action,
479367
+ channel: request2.channel,
478860
479368
  chatId: route.chatId,
478861
479369
  accountId: route.accountId ?? null,
478862
479370
  chatType: route.chatType ?? null,
478863
- threadId: effectiveTextThreadId(request, route),
478864
- message: request.message ?? null,
478865
- replyToMessageId: effectiveTextReplyId(request, route)
479371
+ threadId: effectiveTextThreadId(request2, route),
479372
+ message: request2.message ?? null,
479373
+ replyToMessageId: effectiveTextReplyId(request2, route)
478866
479374
  });
478867
479375
  }
478868
479376
  async function executeMessageChannel(input, options3) {
@@ -478899,8 +479407,8 @@ async function executeMessageChannel(input, options3) {
478899
479407
  channelTurnSources: options3.channelTurnSources
478900
479408
  });
478901
479409
  const requestThreadId = normalized.action === "download-file" ? normalized.threadId : inferredThreadId ?? (normalized.channel === "telegram" && context4.route.chatType === "direct" ? normalized.threadId : context4.route.threadId ?? normalized.threadId);
478902
- const request2 = buildMessageChannelRequest(normalized, normalized.chatId, requestThreadId);
478903
- return await dispatchWithIdempotency(request2, context4, options3.idempotencyScope);
479410
+ const request3 = buildMessageChannelRequest(normalized, normalized.chatId, requestThreadId);
479411
+ return await dispatchWithIdempotency(request3, context4, options3.idempotencyScope);
478904
479412
  }
478905
479413
  if (normalized.channel !== "slack") {
478906
479414
  return `Error: Explicit MessageChannel targets are not supported on ${normalized.channel}.`;
@@ -478921,8 +479429,8 @@ async function executeMessageChannel(input, options3) {
478921
479429
  transport: proactive.transport,
478922
479430
  messageActions: proactive.messageActions
478923
479431
  };
478924
- const request = buildMessageChannelRequest(normalized, proactive.target.chatId, proactive.target.threadId);
478925
- return await dispatchWithIdempotency(request, context3, options3.idempotencyScope);
479432
+ const request2 = buildMessageChannelRequest(normalized, proactive.target.chatId, proactive.target.threadId);
479433
+ return await dispatchWithIdempotency(request2, context3, options3.idempotencyScope);
478926
479434
  } catch (error54) {
478927
479435
  if (error54 instanceof MessageChannelDuplicateActionError)
478928
479436
  throw error54;
@@ -478933,9 +479441,9 @@ async function executeMessageChannel(input, options3) {
478933
479441
  async function executeMessageChannelExternalTool(input, options3) {
478934
479442
  return createMessageChannelExternalToolResult(await executeMessageChannel(input, options3));
478935
479443
  }
478936
- function dispatchWithIdempotency(request, context3, scope) {
478937
- const dispatch = () => dispatchMessageChannelAction({ request, context: context3 });
478938
- const key2 = messageIdempotencyKey(request, context3.route);
479444
+ function dispatchWithIdempotency(request2, context3, scope) {
479445
+ const dispatch = () => dispatchMessageChannelAction({ request: request2, context: context3 });
479446
+ const key2 = messageIdempotencyKey(request2, context3.route);
478939
479447
  return scope ? scope.execute(key2, dispatch) : dispatch();
478940
479448
  }
478941
479449
  var init_message_channel_executor = __esm(() => {
@@ -479971,7 +480479,7 @@ var init_progress_builder = __esm(() => {
479971
480479
  function runtimeKey(runtime) {
479972
480480
  return `${runtime.agent_id}:${runtime.conversation_id}`;
479973
480481
  }
479974
- function sourceKey(source2) {
480482
+ function sourceRouteKey(source2) {
479975
480483
  return [
479976
480484
  source2.channel,
479977
480485
  source2.accountId ?? "",
@@ -479979,12 +480487,26 @@ function sourceKey(source2) {
479979
480487
  source2.threadId ?? ""
479980
480488
  ].join(":");
479981
480489
  }
479982
- function uniqueSources(sources) {
480490
+ function sourceLifecycleKey(source2) {
480491
+ return [
480492
+ sourceRouteKey(source2),
480493
+ source2.messageId ?? "",
480494
+ source2.agentId,
480495
+ source2.conversationId
480496
+ ].join(":");
480497
+ }
480498
+ function uniqueSourcesBy(sources, getKey) {
479983
480499
  const byKey = new Map;
479984
480500
  for (const source2 of sources)
479985
- byKey.set(sourceKey(source2), source2);
480501
+ byKey.set(getKey(source2), source2);
479986
480502
  return [...byKey.values()];
479987
480503
  }
480504
+ function uniqueRoutedSources(sources) {
480505
+ return uniqueSourcesBy(sources, sourceRouteKey);
480506
+ }
480507
+ function uniqueLifecycleSources(sources) {
480508
+ return uniqueSourcesBy(sources, sourceLifecycleKey);
480509
+ }
479988
480510
  function channelTagsForSources(sources) {
479989
480511
  return [...new Set(sources.map((source2) => `channel:${source2.channel}`))];
479990
480512
  }
@@ -480014,11 +480536,11 @@ class ChannelGateway {
480014
480536
  constructor(client, hooks) {
480015
480537
  this.client = client;
480016
480538
  this.hooks = hooks;
480017
- this.disposers.push(client.onMessage((message) => this.handleMessage(message)), client.onExternalToolCall((request) => {
480018
- const state = request.runtime ? this.states.get(runtimeKey(request.runtime)) : undefined;
480539
+ this.disposers.push(client.onMessage((message) => this.handleMessage(message)), client.onExternalToolCall((request2) => {
480540
+ const state = request2.runtime ? this.states.get(runtimeKey(request2.runtime)) : undefined;
480019
480541
  const active = state?.active;
480020
- const sources = active?.sources ?? state?.routedSources ?? [];
480021
- return hooks.executeExternalTool(request, sources, active?.idempotencyScope ?? null);
480542
+ const sources = active?.routingSources ?? state?.routedSources ?? [];
480543
+ return hooks.executeExternalTool(request2, sources, active?.idempotencyScope ?? null);
480022
480544
  }));
480023
480545
  }
480024
480546
  close() {
@@ -480044,12 +480566,12 @@ class ChannelGateway {
480044
480566
  return true;
480045
480567
  }
480046
480568
  state.pendingSourcesByClientMessageId.set(delivery.clientMessageId, {
480047
- sources: uniqueSources(delivery.sources),
480569
+ sources: uniqueLifecycleSources(delivery.sources),
480048
480570
  disposition: "submitting"
480049
480571
  });
480050
480572
  try {
480051
480573
  await this.enqueueRegistration(async () => {
480052
- state.routedSources = uniqueSources([
480574
+ state.routedSources = uniqueRoutedSources([
480053
480575
  ...state.routedSources,
480054
480576
  ...delivery.sources
480055
480577
  ]);
@@ -480087,8 +480609,8 @@ class ChannelGateway {
480087
480609
  const pending = state.pendingSourcesByClientMessageId.get(delivery.clientMessageId);
480088
480610
  if (pending) {
480089
480611
  pending.disposition = "queued";
480090
- pending.acceptedAtQueueRevision = state.queueRevision;
480091
480612
  }
480613
+ this.reconcileExplicitQueueRemovals(state);
480092
480614
  }
480093
480615
  await Promise.all(queuedEvents);
480094
480616
  return true;
@@ -480104,7 +480626,8 @@ class ChannelGateway {
480104
480626
  if (!state.active) {
480105
480627
  recoveredTurn = {
480106
480628
  batchId: `channel-recovered-${crypto.randomUUID()}`,
480107
- sources: uniqueSources(sources),
480629
+ routingSources: uniqueRoutedSources(sources),
480630
+ lifecycleSources: uniqueLifecycleSources(sources),
480108
480631
  progress: createChannelTurnProgressBuilder(),
480109
480632
  richDraft: null,
480110
480633
  idempotencyScope: createMessageChannelIdempotencyScope()
@@ -480145,7 +480668,7 @@ class ChannelGateway {
480145
480668
  return result.accepted;
480146
480669
  }
480147
480670
  setRoutedSources(runtime, sources) {
480148
- this.getState(runtime).routedSources = uniqueSources(sources);
480671
+ this.getState(runtime).routedSources = uniqueRoutedSources(sources);
480149
480672
  }
480150
480673
  getKnownRuntimes() {
480151
480674
  return [...this.states.values()].map((state) => state.runtime);
@@ -480182,7 +480705,6 @@ class ChannelGateway {
480182
480705
  state = {
480183
480706
  runtime,
480184
480707
  pendingSourcesByClientMessageId: new Map,
480185
- queueRevision: 0,
480186
480708
  active: null,
480187
480709
  registrationSignature: null,
480188
480710
  registration: null,
@@ -480299,43 +480821,81 @@ class ChannelGateway {
480299
480821
  }
480300
480822
  handleQueueUpdate(message) {
480301
480823
  const state = this.getState(message.runtime);
480302
- state.queueRevision += 1;
480303
- const nextQueued = new Set(message.queue.map((entry) => entry.client_message_id));
480304
- const removed = [];
480824
+ for (const transition of message.removed) {
480825
+ const pending = state.pendingSourcesByClientMessageId.get(transition.client_message_id);
480826
+ if (pending) {
480827
+ pending.removalDisposition = transition.disposition;
480828
+ }
480829
+ }
480830
+ this.reconcileExplicitQueueRemovals(state);
480831
+ }
480832
+ reconcileExplicitQueueRemovals(state) {
480833
+ const dequeued = [];
480834
+ const cancelled = [];
480305
480835
  for (const [
480306
480836
  clientMessageId,
480307
480837
  pending
480308
480838
  ] of state.pendingSourcesByClientMessageId) {
480309
- if (pending.disposition === "queued" && state.queueRevision > (pending.acceptedAtQueueRevision ?? -1) && !nextQueued.has(clientMessageId)) {
480310
- removed.push({ clientMessageId, sources: pending.sources });
480311
- state.pendingSourcesByClientMessageId.delete(clientMessageId);
480312
- }
480313
- }
480314
- if (!state.active && removed.length > 0) {
480315
- const first = removed[0];
480316
- if (first) {
480317
- this.activateSources(state, first.clientMessageId, removed.flatMap((entry) => entry.sources));
480839
+ if (pending.disposition !== "queued" || !pending.removalDisposition) {
480840
+ continue;
480318
480841
  }
480842
+ const target2 = pending.removalDisposition === "dequeued" ? dequeued : cancelled;
480843
+ target2.push({ clientMessageId, sources: pending.sources });
480844
+ state.pendingSourcesByClientMessageId.delete(clientMessageId);
480845
+ }
480846
+ const firstDequeued = dequeued[0];
480847
+ if (firstDequeued) {
480848
+ this.activateSources(state, firstDequeued.clientMessageId, dequeued.flatMap((entry) => entry.sources));
480849
+ }
480850
+ for (const entry of cancelled) {
480851
+ this.enqueueHook(state, () => this.hooks.onLifecycle({
480852
+ type: "finished",
480853
+ batchId: `channel-${entry.clientMessageId}`,
480854
+ sources: entry.sources,
480855
+ outcome: "cancelled",
480856
+ stopReason: "cancelled"
480857
+ }));
480319
480858
  }
480320
480859
  }
480321
480860
  activateSources(state, clientMessageId, sources) {
480322
480861
  if (state.active) {
480862
+ const knownLifecycleKeys = new Set(state.active.lifecycleSources.map(sourceLifecycleKey));
480863
+ const addedLifecycleSources = uniqueLifecycleSources(sources).filter((source2) => !knownLifecycleKeys.has(sourceLifecycleKey(source2)));
480864
+ if (addedLifecycleSources.length === 0)
480865
+ return;
480866
+ state.active.lifecycleSources = uniqueLifecycleSources([
480867
+ ...state.active.lifecycleSources,
480868
+ ...addedLifecycleSources
480869
+ ]);
480870
+ state.active.routingSources = uniqueRoutedSources([
480871
+ ...state.active.routingSources,
480872
+ ...sources
480873
+ ]);
480874
+ const processingEvent2 = {
480875
+ type: "processing",
480876
+ batchId: state.active.batchId,
480877
+ sources: addedLifecycleSources
480878
+ };
480879
+ this.enqueueHook(state, () => this.hooks.onLifecycle(processingEvent2));
480323
480880
  return;
480324
480881
  }
480882
+ const routingSources = uniqueRoutedSources(sources);
480883
+ const lifecycleSources = uniqueLifecycleSources(sources);
480325
480884
  state.active = {
480326
480885
  batchId: `channel-${clientMessageId}`,
480327
- sources: uniqueSources(sources),
480886
+ routingSources,
480887
+ lifecycleSources,
480328
480888
  progress: createChannelTurnProgressBuilder(),
480329
480889
  richDraft: this.hooks.createRichDraft?.({
480330
480890
  batchId: `channel-${clientMessageId}`,
480331
- sources
480891
+ sources: routingSources
480332
480892
  }) ?? null,
480333
480893
  idempotencyScope: createMessageChannelIdempotencyScope()
480334
480894
  };
480335
480895
  const processingEvent = {
480336
480896
  type: "processing",
480337
480897
  batchId: state.active.batchId,
480338
- sources: state.active.sources
480898
+ sources: state.active.lifecycleSources
480339
480899
  };
480340
480900
  this.enqueueHook(state, () => this.hooks.onLifecycle(processingEvent));
480341
480901
  }
@@ -480353,7 +480913,7 @@ class ChannelGateway {
480353
480913
  this.enqueueHook(state, () => this.hooks.onProgress({
480354
480914
  type: "progress",
480355
480915
  batchId: active.batchId,
480356
- sources: active.sources,
480916
+ sources: active.routingSources,
480357
480917
  ...update2
480358
480918
  }));
480359
480919
  }
@@ -480373,7 +480933,7 @@ class ChannelGateway {
480373
480933
  this.enqueueHook(state, () => this.hooks.onLifecycle({
480374
480934
  type: "finished",
480375
480935
  batchId: active.batchId,
480376
- sources: active.sources,
480936
+ sources: active.lifecycleSources,
480377
480937
  outcome: lifecycleOutcome(terminal.stopReason),
480378
480938
  stopReason: terminal.stopReason,
480379
480939
  ...terminal.runId ?? active.runId ? { runId: terminal.runId ?? active.runId } : {},
@@ -480389,9 +480949,9 @@ class ChannelGateway {
480389
480949
  }));
480390
480950
  if (!state)
480391
480951
  return;
480392
- const sources = state.active?.sources ?? [];
480952
+ const sources = state.active?.routingSources ?? [];
480393
480953
  state.replayedControlRequestIds.add(message.request_id);
480394
- const sourceScopes = new Map(sources.map((source3) => [sourceKey(source3), source3]));
480954
+ const sourceScopes = new Map(sources.map((source3) => [sourceRouteKey(source3), source3]));
480395
480955
  if (sourceScopes.size !== 1)
480396
480956
  return;
480397
480957
  const source2 = [...sourceScopes.values()][0];
@@ -481644,12 +482204,12 @@ function createRoutedRuntimeRegistrationRefresher(options3) {
481644
482204
  });
481645
482205
  return run;
481646
482206
  };
481647
- const waitForRetry = () => new Promise((resolve34) => {
481648
- resolveRetry = resolve34;
482207
+ const waitForRetry = () => new Promise((resolve35) => {
482208
+ resolveRetry = resolve35;
481649
482209
  retryTimer = setTimeout(() => {
481650
482210
  retryTimer = null;
481651
482211
  resolveRetry = null;
481652
- resolve34();
482212
+ resolve35();
481653
482213
  }, retryDelayMs);
481654
482214
  retryTimer.unref?.();
481655
482215
  });
@@ -481814,16 +482374,16 @@ async function executeChannelServiceCommand(command) {
481814
482374
  await Promise.all(detachedTasks);
481815
482375
  return responses;
481816
482376
  }
481817
- async function executeGatewayServiceCommand(request) {
481818
- if (request.kind === "protocol") {
482377
+ async function executeGatewayServiceCommand(request2) {
482378
+ if (request2.kind === "protocol") {
481819
482379
  return {
481820
482380
  kind: "protocol",
481821
- messages: await executeChannelServiceCommand(request.command)
482381
+ messages: await executeChannelServiceCommand(request2.command)
481822
482382
  };
481823
482383
  }
481824
482384
  return {
481825
482385
  kind: "text",
481826
- text: await handleChannelsSlashCommand(request.runtime, request.args)
482386
+ text: await handleChannelsSlashCommand(request2.runtime, request2.args)
481827
482387
  };
481828
482388
  }
481829
482389
  function gatewayClientMessageId(delivery) {
@@ -481910,17 +482470,17 @@ async function startLocalChannelGateway(options3) {
481910
482470
  buildExternalTool: async (runtime) => {
481911
482471
  return buildGatewayMessageChannelTool(registry2.resolveTurnSourcesForScope(runtime.agent_id, runtime.conversation_id));
481912
482472
  },
481913
- executeExternalTool: async (request, sources, idempotencyScope) => {
481914
- if (request.tool_name !== "MessageChannel" || !request.runtime) {
481915
- throw new Error(`Unsupported gateway tool: ${request.tool_name}`);
482473
+ executeExternalTool: async (request2, sources, idempotencyScope) => {
482474
+ if (request2.tool_name !== "MessageChannel" || !request2.runtime) {
482475
+ throw new Error(`Unsupported gateway tool: ${request2.tool_name}`);
481916
482476
  }
481917
482477
  return await executeLocalMessageChannelExternalTool({
481918
- ...request.input,
481919
- channel: String(request.input.channel ?? ""),
481920
- action: String(request.input.action ?? ""),
482478
+ ...request2.input,
482479
+ channel: String(request2.input.channel ?? ""),
482480
+ action: String(request2.input.action ?? ""),
481921
482481
  parentScope: {
481922
- agentId: request.runtime.agent_id,
481923
- conversationId: request.runtime.conversation_id
482482
+ agentId: request2.runtime.agent_id,
482483
+ conversationId: request2.runtime.conversation_id
481924
482484
  },
481925
482485
  channelTurnSources: sources
481926
482486
  }, idempotencyScope);
@@ -482229,14 +482789,14 @@ var exports_channel_gateway = {};
482229
482789
  __export(exports_channel_gateway, {
482230
482790
  runChannelGatewaySubcommand: () => runChannelGatewaySubcommand
482231
482791
  });
482232
- import { parseArgs as parseArgs17 } from "node:util";
482792
+ import { parseArgs as parseArgs18 } from "node:util";
482233
482793
  function isGatewayCommandEnvelope(value) {
482234
482794
  return Boolean(value && typeof value === "object" && "type" in value && value.type === "command" && "requestId" in value && typeof value.requestId === "string" && "command" in value && value.command && typeof value.command === "object");
482235
482795
  }
482236
482796
  async function runChannelGatewaySubcommand(argv) {
482237
482797
  let values2;
482238
482798
  try {
482239
- ({ values: values2 } = parseArgs17({
482799
+ ({ values: values2 } = parseArgs18({
482240
482800
  args: argv,
482241
482801
  strict: true,
482242
482802
  allowPositionals: false,
@@ -482275,7 +482835,7 @@ async function runChannelGatewaySubcommand(argv) {
482275
482835
  await ensureChannelRuntimeInstalled2(channelName);
482276
482836
  }
482277
482837
  }
482278
- return await new Promise((resolve34) => {
482838
+ return await new Promise((resolve35) => {
482279
482839
  let closing2 = false;
482280
482840
  let closeGateway = null;
482281
482841
  const finish = (code2) => {
@@ -482283,10 +482843,10 @@ async function runChannelGatewaySubcommand(argv) {
482283
482843
  return;
482284
482844
  closing2 = true;
482285
482845
  if (!closeGateway) {
482286
- resolve34(code2);
482846
+ resolve35(code2);
482287
482847
  return;
482288
482848
  }
482289
- closeGateway().finally(() => resolve34(code2));
482849
+ closeGateway().finally(() => resolve35(code2));
482290
482850
  };
482291
482851
  startLocalChannelGateway({
482292
482852
  appServerUrl,
@@ -482334,7 +482894,7 @@ async function runChannelGatewaySubcommand(argv) {
482334
482894
  gateway.close();
482335
482895
  }).catch((error54) => {
482336
482896
  console.error(error54 instanceof Error ? error54.message : String(error54));
482337
- resolve34(1);
482897
+ resolve35(1);
482338
482898
  });
482339
482899
  });
482340
482900
  }
@@ -482372,6 +482932,7 @@ function subcommandNeedsEarlyBackendMode(command) {
482372
482932
  case "messages":
482373
482933
  case "mods":
482374
482934
  case "remote":
482935
+ case "sandbox":
482375
482936
  case "server":
482376
482937
  case "shared-memory":
482377
482938
  case "skills":
@@ -482406,6 +482967,8 @@ async function runSubcommand(argv) {
482406
482967
  return runEnvironmentsSubcommand(rest3);
482407
482968
  case "mods":
482408
482969
  return runModsSubcommand(rest3);
482970
+ case "sandbox":
482971
+ return runSandboxSubcommand(rest3);
482409
482972
  case "server":
482410
482973
  return runServerSubcommand(rest3);
482411
482974
  case "remote":
@@ -482451,6 +483014,7 @@ var init_router = __esm(async () => {
482451
483014
  init_local_backend2();
482452
483015
  init_memory7();
482453
483016
  init_messages10();
483017
+ init_sandbox2();
482454
483018
  init_shared_memory();
482455
483019
  init_skills4();
482456
483020
  init_trajectories();
@@ -482528,10 +483092,10 @@ async function detectAndEnableKittyProtocol() {
482528
483092
  detectionComplete = true;
482529
483093
  return;
482530
483094
  }
482531
- return new Promise((resolve34) => {
483095
+ return new Promise((resolve35) => {
482532
483096
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
482533
483097
  detectionComplete = true;
482534
- resolve34();
483098
+ resolve35();
482535
483099
  return;
482536
483100
  }
482537
483101
  const originalRawMode = process.stdin.isRaw;
@@ -482564,7 +483128,7 @@ async function detectAndEnableKittyProtocol() {
482564
483128
  console.error("[kitty] protocol query unsupported; enabled anyway (best-effort)");
482565
483129
  }
482566
483130
  detectionComplete = true;
482567
- resolve34();
483131
+ resolve35();
482568
483132
  };
482569
483133
  const handleData = (data) => {
482570
483134
  if (timeoutId === undefined) {
@@ -483201,9 +483765,9 @@ function writeWireMessage(msg) {
483201
483765
  async function writeWireMessageAsync(msg) {
483202
483766
  const line = `${JSON.stringify(stampWireMessage(msg))}
483203
483767
  `;
483204
- return await new Promise((resolve34, reject) => {
483768
+ return await new Promise((resolve35, reject) => {
483205
483769
  if (process.stdout.destroyed || process.stdout.writableEnded) {
483206
- resolve34(false);
483770
+ resolve35(false);
483207
483771
  return;
483208
483772
  }
483209
483773
  process.stdout.write(line, (error54) => {
@@ -483211,7 +483775,7 @@ async function writeWireMessageAsync(msg) {
483211
483775
  reject(error54);
483212
483776
  return;
483213
483777
  }
483214
- resolve34(true);
483778
+ resolve35(true);
483215
483779
  });
483216
483780
  });
483217
483781
  }
@@ -484462,8 +485026,8 @@ async function parseErrorResponse2(input) {
484462
485026
  const errorClass = OAUTH_ERRORS[error54] || ServerError;
484463
485027
  return new errorClass(error_description || "", error_uri);
484464
485028
  } catch (error54) {
484465
- const errorMessage2 = `${statusCode2 ? `HTTP ${statusCode2}: ` : ""}Invalid OAuth error response: ${error54}. Raw body: ${body3}`;
484466
- return new ServerError(errorMessage2);
485029
+ const errorMessage3 = `${statusCode2 ? `HTTP ${statusCode2}: ` : ""}Invalid OAuth error response: ${error54}. Raw body: ${body3}`;
485030
+ return new ServerError(errorMessage3);
484467
485031
  }
484468
485032
  }
484469
485033
  async function auth(provider, options3) {
@@ -485094,8 +485658,8 @@ class Protocol {
485094
485658
  this._taskStore = _options?.taskStore;
485095
485659
  this._taskMessageQueue = _options?.taskMessageQueue;
485096
485660
  if (this._taskStore) {
485097
- this.setRequestHandler(GetTaskRequestSchema, async (request, extra) => {
485098
- const task2 = await this._taskStore.getTask(request.params.taskId, extra.sessionId);
485661
+ this.setRequestHandler(GetTaskRequestSchema, async (request2, extra) => {
485662
+ const task2 = await this._taskStore.getTask(request2.params.taskId, extra.sessionId);
485099
485663
  if (!task2) {
485100
485664
  throw new McpError(ErrorCode.InvalidParams, "Failed to retrieve task: Task not found");
485101
485665
  }
@@ -485103,9 +485667,9 @@ class Protocol {
485103
485667
  ...task2
485104
485668
  };
485105
485669
  });
485106
- this.setRequestHandler(GetTaskPayloadRequestSchema, async (request, extra) => {
485670
+ this.setRequestHandler(GetTaskPayloadRequestSchema, async (request2, extra) => {
485107
485671
  const handleTaskResult = async () => {
485108
- const taskId = request.params.taskId;
485672
+ const taskId = request2.params.taskId;
485109
485673
  if (this._taskMessageQueue) {
485110
485674
  let queuedMessage;
485111
485675
  while (queuedMessage = await this._taskMessageQueue.dequeue(taskId, extra.sessionId)) {
@@ -485118,8 +485682,8 @@ class Protocol {
485118
485682
  if (queuedMessage.type === "response") {
485119
485683
  resolver(message);
485120
485684
  } else {
485121
- const errorMessage2 = message;
485122
- const error54 = new McpError(errorMessage2.error.code, errorMessage2.error.message, errorMessage2.error.data);
485685
+ const errorMessage3 = message;
485686
+ const error54 = new McpError(errorMessage3.error.code, errorMessage3.error.message, errorMessage3.error.data);
485123
485687
  resolver(error54);
485124
485688
  }
485125
485689
  } else {
@@ -485156,9 +485720,9 @@ class Protocol {
485156
485720
  };
485157
485721
  return await handleTaskResult();
485158
485722
  });
485159
- this.setRequestHandler(ListTasksRequestSchema, async (request, extra) => {
485723
+ this.setRequestHandler(ListTasksRequestSchema, async (request2, extra) => {
485160
485724
  try {
485161
- const { tasks: tasks2, nextCursor } = await this._taskStore.listTasks(request.params?.cursor, extra.sessionId);
485725
+ const { tasks: tasks2, nextCursor } = await this._taskStore.listTasks(request2.params?.cursor, extra.sessionId);
485162
485726
  return {
485163
485727
  tasks: tasks2,
485164
485728
  nextCursor,
@@ -485168,20 +485732,20 @@ class Protocol {
485168
485732
  throw new McpError(ErrorCode.InvalidParams, `Failed to list tasks: ${error54 instanceof Error ? error54.message : String(error54)}`);
485169
485733
  }
485170
485734
  });
485171
- this.setRequestHandler(CancelTaskRequestSchema, async (request, extra) => {
485735
+ this.setRequestHandler(CancelTaskRequestSchema, async (request2, extra) => {
485172
485736
  try {
485173
- const task2 = await this._taskStore.getTask(request.params.taskId, extra.sessionId);
485737
+ const task2 = await this._taskStore.getTask(request2.params.taskId, extra.sessionId);
485174
485738
  if (!task2) {
485175
- throw new McpError(ErrorCode.InvalidParams, `Task not found: ${request.params.taskId}`);
485739
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${request2.params.taskId}`);
485176
485740
  }
485177
485741
  if (isTerminal(task2.status)) {
485178
485742
  throw new McpError(ErrorCode.InvalidParams, `Cannot cancel task in terminal status: ${task2.status}`);
485179
485743
  }
485180
- await this._taskStore.updateTaskStatus(request.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId);
485181
- this._clearTaskQueue(request.params.taskId);
485182
- const cancelledTask = await this._taskStore.getTask(request.params.taskId, extra.sessionId);
485744
+ await this._taskStore.updateTaskStatus(request2.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId);
485745
+ this._clearTaskQueue(request2.params.taskId);
485746
+ const cancelledTask = await this._taskStore.getTask(request2.params.taskId, extra.sessionId);
485183
485747
  if (!cancelledTask) {
485184
- throw new McpError(ErrorCode.InvalidParams, `Task not found after cancellation: ${request.params.taskId}`);
485748
+ throw new McpError(ErrorCode.InvalidParams, `Task not found after cancellation: ${request2.params.taskId}`);
485185
485749
  }
485186
485750
  return {
485187
485751
  _meta: {},
@@ -485297,14 +485861,14 @@ class Protocol {
485297
485861
  }
485298
485862
  Promise.resolve().then(() => handler(notification)).catch((error54) => this._onerror(new Error(`Uncaught error in notification handler: ${error54}`)));
485299
485863
  }
485300
- _onrequest(request, extra) {
485301
- const handler = this._requestHandlers.get(request.method) ?? this.fallbackRequestHandler;
485864
+ _onrequest(request2, extra) {
485865
+ const handler = this._requestHandlers.get(request2.method) ?? this.fallbackRequestHandler;
485302
485866
  const capturedTransport = this._transport;
485303
- const relatedTaskId = request.params?._meta?.[RELATED_TASK_META_KEY]?.taskId;
485867
+ const relatedTaskId = request2.params?._meta?.[RELATED_TASK_META_KEY]?.taskId;
485304
485868
  if (handler === undefined) {
485305
485869
  const errorResponse = {
485306
485870
  jsonrpc: "2.0",
485307
- id: request.id,
485871
+ id: request2.id,
485308
485872
  error: {
485309
485873
  code: ErrorCode.MethodNotFound,
485310
485874
  message: "Method not found"
@@ -485322,17 +485886,17 @@ class Protocol {
485322
485886
  return;
485323
485887
  }
485324
485888
  const abortController = new AbortController;
485325
- this._requestHandlerAbortControllers.set(request.id, abortController);
485326
- const taskCreationParams = isTaskAugmentedRequestParams(request.params) ? request.params.task : undefined;
485327
- const taskStore = this._taskStore ? this.requestTaskStore(request, capturedTransport?.sessionId) : undefined;
485889
+ this._requestHandlerAbortControllers.set(request2.id, abortController);
485890
+ const taskCreationParams = isTaskAugmentedRequestParams(request2.params) ? request2.params.task : undefined;
485891
+ const taskStore = this._taskStore ? this.requestTaskStore(request2, capturedTransport?.sessionId) : undefined;
485328
485892
  const fullExtra = {
485329
485893
  signal: abortController.signal,
485330
485894
  sessionId: capturedTransport?.sessionId,
485331
- _meta: request.params?._meta,
485895
+ _meta: request2.params?._meta,
485332
485896
  sendNotification: async (notification) => {
485333
485897
  if (abortController.signal.aborted)
485334
485898
  return;
485335
- const notificationOptions = { relatedRequestId: request.id };
485899
+ const notificationOptions = { relatedRequestId: request2.id };
485336
485900
  if (relatedTaskId) {
485337
485901
  notificationOptions.relatedTask = { taskId: relatedTaskId };
485338
485902
  }
@@ -485342,7 +485906,7 @@ class Protocol {
485342
485906
  if (abortController.signal.aborted) {
485343
485907
  throw new McpError(ErrorCode.ConnectionClosed, "Request was cancelled");
485344
485908
  }
485345
- const requestOptions = { ...options3, relatedRequestId: request.id };
485909
+ const requestOptions = { ...options3, relatedRequestId: request2.id };
485346
485910
  if (relatedTaskId && !requestOptions.relatedTask) {
485347
485911
  requestOptions.relatedTask = { taskId: relatedTaskId };
485348
485912
  }
@@ -485353,7 +485917,7 @@ class Protocol {
485353
485917
  return await this.request(r5, resultSchema, requestOptions);
485354
485918
  },
485355
485919
  authInfo: extra?.authInfo,
485356
- requestId: request.id,
485920
+ requestId: request2.id,
485357
485921
  requestInfo: extra?.requestInfo,
485358
485922
  taskId: relatedTaskId,
485359
485923
  taskStore,
@@ -485363,16 +485927,16 @@ class Protocol {
485363
485927
  };
485364
485928
  Promise.resolve().then(() => {
485365
485929
  if (taskCreationParams) {
485366
- this.assertTaskHandlerCapability(request.method);
485930
+ this.assertTaskHandlerCapability(request2.method);
485367
485931
  }
485368
- }).then(() => handler(request, fullExtra)).then(async (result) => {
485932
+ }).then(() => handler(request2, fullExtra)).then(async (result) => {
485369
485933
  if (abortController.signal.aborted) {
485370
485934
  return;
485371
485935
  }
485372
485936
  const response = {
485373
485937
  result,
485374
485938
  jsonrpc: "2.0",
485375
- id: request.id
485939
+ id: request2.id
485376
485940
  };
485377
485941
  if (relatedTaskId && this._taskMessageQueue) {
485378
485942
  await this._enqueueTaskMessage(relatedTaskId, {
@@ -485389,7 +485953,7 @@ class Protocol {
485389
485953
  }
485390
485954
  const errorResponse = {
485391
485955
  jsonrpc: "2.0",
485392
- id: request.id,
485956
+ id: request2.id,
485393
485957
  error: {
485394
485958
  code: Number.isSafeInteger(error54["code"]) ? error54["code"] : ErrorCode.InternalError,
485395
485959
  message: error54.message ?? "Internal error",
@@ -485406,8 +485970,8 @@ class Protocol {
485406
485970
  await capturedTransport?.send(errorResponse);
485407
485971
  }
485408
485972
  }).catch((error54) => this._onerror(new Error(`Failed to send response: ${error54}`))).finally(() => {
485409
- if (this._requestHandlerAbortControllers.get(request.id) === abortController) {
485410
- this._requestHandlerAbortControllers.delete(request.id);
485973
+ if (this._requestHandlerAbortControllers.get(request2.id) === abortController) {
485974
+ this._requestHandlerAbortControllers.delete(request2.id);
485411
485975
  }
485412
485976
  });
485413
485977
  }
@@ -485481,11 +486045,11 @@ class Protocol {
485481
486045
  async close() {
485482
486046
  await this._transport?.close();
485483
486047
  }
485484
- async* requestStream(request, resultSchema, options3) {
486048
+ async* requestStream(request2, resultSchema, options3) {
485485
486049
  const { task: task2 } = options3 ?? {};
485486
486050
  if (!task2) {
485487
486051
  try {
485488
- const result = await this.request(request, resultSchema, options3);
486052
+ const result = await this.request(request2, resultSchema, options3);
485489
486053
  yield { type: "result", result };
485490
486054
  } catch (error54) {
485491
486055
  yield {
@@ -485497,7 +486061,7 @@ class Protocol {
485497
486061
  }
485498
486062
  let taskId;
485499
486063
  try {
485500
- const createResult = await this.request(request, CreateTaskResultSchema, options3);
486064
+ const createResult = await this.request(request2, CreateTaskResultSchema, options3);
485501
486065
  if (createResult.task) {
485502
486066
  taskId = createResult.task.taskId;
485503
486067
  yield { type: "taskCreated", task: createResult.task };
@@ -485530,7 +486094,7 @@ class Protocol {
485530
486094
  return;
485531
486095
  }
485532
486096
  const pollInterval = task3.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1000;
485533
- await new Promise((resolve34) => setTimeout(resolve34, pollInterval));
486097
+ await new Promise((resolve35) => setTimeout(resolve35, pollInterval));
485534
486098
  options3?.signal?.throwIfAborted();
485535
486099
  }
485536
486100
  } catch (error54) {
@@ -485540,9 +486104,9 @@ class Protocol {
485540
486104
  };
485541
486105
  }
485542
486106
  }
485543
- request(request, resultSchema, options3) {
486107
+ request(request2, resultSchema, options3) {
485544
486108
  const { relatedRequestId, resumptionToken, onresumptiontoken, task: task2, relatedTask } = options3 ?? {};
485545
- return new Promise((resolve34, reject) => {
486109
+ return new Promise((resolve35, reject) => {
485546
486110
  const earlyReject = (error54) => {
485547
486111
  reject(error54);
485548
486112
  };
@@ -485552,9 +486116,9 @@ class Protocol {
485552
486116
  }
485553
486117
  if (this._options?.enforceStrictCapabilities === true) {
485554
486118
  try {
485555
- this.assertCapabilityForMethod(request.method);
486119
+ this.assertCapabilityForMethod(request2.method);
485556
486120
  if (task2) {
485557
- this.assertTaskCapability(request.method);
486121
+ this.assertTaskCapability(request2.method);
485558
486122
  }
485559
486123
  } catch (e2) {
485560
486124
  earlyReject(e2);
@@ -485564,16 +486128,16 @@ class Protocol {
485564
486128
  options3?.signal?.throwIfAborted();
485565
486129
  const messageId2 = this._requestMessageId++;
485566
486130
  const jsonrpcRequest = {
485567
- ...request,
486131
+ ...request2,
485568
486132
  jsonrpc: "2.0",
485569
486133
  id: messageId2
485570
486134
  };
485571
486135
  if (options3?.onprogress) {
485572
486136
  this._progressHandlers.set(messageId2, options3.onprogress);
485573
486137
  jsonrpcRequest.params = {
485574
- ...request.params,
486138
+ ...request2.params,
485575
486139
  _meta: {
485576
- ...request.params?._meta || {},
486140
+ ...request2.params?._meta || {},
485577
486141
  progressToken: messageId2
485578
486142
  }
485579
486143
  };
@@ -485620,7 +486184,7 @@ class Protocol {
485620
486184
  if (!parseResult.success) {
485621
486185
  reject(parseResult.error);
485622
486186
  } else {
485623
- resolve34(parseResult.data);
486187
+ resolve35(parseResult.data);
485624
486188
  }
485625
486189
  } catch (error54) {
485626
486190
  reject(error54);
@@ -485749,8 +486313,8 @@ class Protocol {
485749
486313
  setRequestHandler(requestSchema, handler) {
485750
486314
  const method = getMethodLiteral(requestSchema);
485751
486315
  this.assertRequestHandlerCapability(method);
485752
- this._requestHandlers.set(method, (request, extra) => {
485753
- const parsed = parseWithCompat(requestSchema, request);
486316
+ this._requestHandlers.set(method, (request2, extra) => {
486317
+ const parsed = parseWithCompat(requestSchema, request2);
485754
486318
  return Promise.resolve(handler(parsed, extra));
485755
486319
  });
485756
486320
  }
@@ -485811,31 +486375,31 @@ class Protocol {
485811
486375
  interval = task2.pollInterval;
485812
486376
  }
485813
486377
  } catch {}
485814
- return new Promise((resolve34, reject) => {
486378
+ return new Promise((resolve35, reject) => {
485815
486379
  if (signal.aborted) {
485816
486380
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
485817
486381
  return;
485818
486382
  }
485819
- const timeoutId = setTimeout(resolve34, interval);
486383
+ const timeoutId = setTimeout(resolve35, interval);
485820
486384
  signal.addEventListener("abort", () => {
485821
486385
  clearTimeout(timeoutId);
485822
486386
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
485823
486387
  }, { once: true });
485824
486388
  });
485825
486389
  }
485826
- requestTaskStore(request, sessionId) {
486390
+ requestTaskStore(request2, sessionId) {
485827
486391
  const taskStore = this._taskStore;
485828
486392
  if (!taskStore) {
485829
486393
  throw new Error("No task store configured");
485830
486394
  }
485831
486395
  return {
485832
486396
  createTask: async (taskParams) => {
485833
- if (!request) {
486397
+ if (!request2) {
485834
486398
  throw new Error("No request provided");
485835
486399
  }
485836
- return await taskStore.createTask(taskParams, request.id, {
485837
- method: request.method,
485838
- params: request.params
486400
+ return await taskStore.createTask(taskParams, request2.id, {
486401
+ method: request2.method,
486402
+ params: request2.params
485839
486403
  }, sessionId);
485840
486404
  },
485841
486405
  getTask: async (taskId) => {
@@ -488801,7 +489365,7 @@ var require_compile = __commonJS((exports) => {
488801
489365
  const schOrFunc = root2.refs[ref6];
488802
489366
  if (schOrFunc)
488803
489367
  return schOrFunc;
488804
- let _sch = resolve34.call(this, root2, ref6);
489368
+ let _sch = resolve35.call(this, root2, ref6);
488805
489369
  if (_sch === undefined) {
488806
489370
  const schema5 = (_a8 = root2.localRefs) === null || _a8 === undefined ? undefined : _a8[ref6];
488807
489371
  const { schemaId } = this.opts;
@@ -488828,7 +489392,7 @@ var require_compile = __commonJS((exports) => {
488828
489392
  function sameSchemaEnv(s1, s22) {
488829
489393
  return s1.schema === s22.schema && s1.root === s22.root && s1.baseId === s22.baseId;
488830
489394
  }
488831
- function resolve34(root2, ref6) {
489395
+ function resolve35(root2, ref6) {
488832
489396
  let sch;
488833
489397
  while (typeof (sch = this.refs[ref6]) == "string")
488834
489398
  ref6 = sch;
@@ -489414,7 +489978,7 @@ var require_fast_uri = __commonJS((exports, module3) => {
489414
489978
  }
489415
489979
  return uri;
489416
489980
  }
489417
- function resolve34(baseURI, relativeURI, options3) {
489981
+ function resolve35(baseURI, relativeURI, options3) {
489418
489982
  const schemelessOptions = options3 ? Object.assign({ scheme: "null" }, options3) : { scheme: "null" };
489419
489983
  const resolved = resolveComponent(parse9(baseURI, schemelessOptions), parse9(relativeURI, schemelessOptions), schemelessOptions, true);
489420
489984
  schemelessOptions.skipEscape = true;
@@ -489679,7 +490243,7 @@ var require_fast_uri = __commonJS((exports, module3) => {
489679
490243
  var fastUri = {
489680
490244
  SCHEMES,
489681
490245
  normalize: normalize6,
489682
- resolve: resolve34,
490246
+ resolve: resolve35,
489683
490247
  resolveComponent,
489684
490248
  equal: equal3,
489685
490249
  serialize,
@@ -492584,8 +493148,8 @@ class ExperimentalClientTasks {
492584
493148
  async cancelTask(taskId, options3) {
492585
493149
  return this._client.cancelTask({ taskId }, options3);
492586
493150
  }
492587
- requestStream(request, resultSchema, options3) {
492588
- return this._client.requestStream(request, resultSchema, options3);
493151
+ requestStream(request2, resultSchema, options3) {
493152
+ return this._client.requestStream(request2, resultSchema, options3);
492589
493153
  }
492590
493154
  }
492591
493155
  var init_client8 = __esm(() => {
@@ -492736,11 +493300,11 @@ var init_client9 = __esm(() => {
492736
493300
  }
492737
493301
  const method = methodValue;
492738
493302
  if (method === "elicitation/create") {
492739
- const wrappedHandler = async (request, extra) => {
492740
- const validatedRequest = safeParse4(ElicitRequestSchema, request);
493303
+ const wrappedHandler = async (request2, extra) => {
493304
+ const validatedRequest = safeParse4(ElicitRequestSchema, request2);
492741
493305
  if (!validatedRequest.success) {
492742
- const errorMessage2 = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
492743
- throw new McpError(ErrorCode.InvalidParams, `Invalid elicitation request: ${errorMessage2}`);
493306
+ const errorMessage3 = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
493307
+ throw new McpError(ErrorCode.InvalidParams, `Invalid elicitation request: ${errorMessage3}`);
492744
493308
  }
492745
493309
  const { params } = validatedRequest.data;
492746
493310
  params.mode = params.mode ?? "form";
@@ -492751,19 +493315,19 @@ var init_client9 = __esm(() => {
492751
493315
  if (params.mode === "url" && !supportsUrlMode) {
492752
493316
  throw new McpError(ErrorCode.InvalidParams, "Client does not support URL-mode elicitation requests");
492753
493317
  }
492754
- const result = await Promise.resolve(handler(request, extra));
493318
+ const result = await Promise.resolve(handler(request2, extra));
492755
493319
  if (params.task) {
492756
493320
  const taskValidationResult = safeParse4(CreateTaskResultSchema, result);
492757
493321
  if (!taskValidationResult.success) {
492758
- const errorMessage2 = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
492759
- throw new McpError(ErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage2}`);
493322
+ const errorMessage3 = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
493323
+ throw new McpError(ErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage3}`);
492760
493324
  }
492761
493325
  return taskValidationResult.data;
492762
493326
  }
492763
493327
  const validationResult = safeParse4(ElicitResultSchema, result);
492764
493328
  if (!validationResult.success) {
492765
- const errorMessage2 = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
492766
- throw new McpError(ErrorCode.InvalidParams, `Invalid elicitation result: ${errorMessage2}`);
493329
+ const errorMessage3 = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
493330
+ throw new McpError(ErrorCode.InvalidParams, `Invalid elicitation result: ${errorMessage3}`);
492767
493331
  }
492768
493332
  const validatedResult = validationResult.data;
492769
493333
  const requestedSchema = params.mode === "form" ? params.requestedSchema : undefined;
@@ -492779,19 +493343,19 @@ var init_client9 = __esm(() => {
492779
493343
  return super.setRequestHandler(requestSchema, wrappedHandler);
492780
493344
  }
492781
493345
  if (method === "sampling/createMessage") {
492782
- const wrappedHandler = async (request, extra) => {
492783
- const validatedRequest = safeParse4(CreateMessageRequestSchema, request);
493346
+ const wrappedHandler = async (request2, extra) => {
493347
+ const validatedRequest = safeParse4(CreateMessageRequestSchema, request2);
492784
493348
  if (!validatedRequest.success) {
492785
- const errorMessage2 = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
492786
- throw new McpError(ErrorCode.InvalidParams, `Invalid sampling request: ${errorMessage2}`);
493349
+ const errorMessage3 = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
493350
+ throw new McpError(ErrorCode.InvalidParams, `Invalid sampling request: ${errorMessage3}`);
492787
493351
  }
492788
493352
  const { params } = validatedRequest.data;
492789
- const result = await Promise.resolve(handler(request, extra));
493353
+ const result = await Promise.resolve(handler(request2, extra));
492790
493354
  if (params.task) {
492791
493355
  const taskValidationResult = safeParse4(CreateTaskResultSchema, result);
492792
493356
  if (!taskValidationResult.success) {
492793
- const errorMessage2 = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
492794
- throw new McpError(ErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage2}`);
493357
+ const errorMessage3 = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
493358
+ throw new McpError(ErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage3}`);
492795
493359
  }
492796
493360
  return taskValidationResult.data;
492797
493361
  }
@@ -492799,8 +493363,8 @@ var init_client9 = __esm(() => {
492799
493363
  const resultSchema = hasTools ? CreateMessageResultWithToolsSchema : CreateMessageResultSchema;
492800
493364
  const validationResult = safeParse4(resultSchema, result);
492801
493365
  if (!validationResult.success) {
492802
- const errorMessage2 = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
492803
- throw new McpError(ErrorCode.InvalidParams, `Invalid sampling result: ${errorMessage2}`);
493366
+ const errorMessage3 = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
493367
+ throw new McpError(ErrorCode.InvalidParams, `Invalid sampling result: ${errorMessage3}`);
492804
493368
  }
492805
493369
  return validationResult.data;
492806
493370
  };
@@ -493498,7 +494062,7 @@ class SSEClientTransport {
493498
494062
  }
493499
494063
  _startOrAuth() {
493500
494064
  const fetchImpl = this?._eventSourceInit?.fetch ?? this._fetch ?? fetch;
493501
- return new Promise((resolve34, reject) => {
494065
+ return new Promise((resolve35, reject) => {
493502
494066
  this._eventSource = new EventSource2(this._url.href, {
493503
494067
  ...this._eventSourceInit,
493504
494068
  fetch: async (url2, init) => {
@@ -493519,7 +494083,7 @@ class SSEClientTransport {
493519
494083
  this._abortController = new AbortController;
493520
494084
  this._eventSource.onerror = (event2) => {
493521
494085
  if (event2.code === 401 && this._authProvider) {
493522
- this._authThenStart().then(resolve34, reject);
494086
+ this._authThenStart().then(resolve35, reject);
493523
494087
  return;
493524
494088
  }
493525
494089
  const error54 = new SseError(event2.code, event2.message, event2);
@@ -493540,7 +494104,7 @@ class SSEClientTransport {
493540
494104
  this.close();
493541
494105
  return;
493542
494106
  }
493543
- resolve34();
494107
+ resolve35();
493544
494108
  });
493545
494109
  this._eventSource.onmessage = (event2) => {
493546
494110
  const messageEvent2 = event2;
@@ -493713,7 +494277,7 @@ class StdioClientTransport {
493713
494277
  if (this._process) {
493714
494278
  throw new Error("StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.");
493715
494279
  }
493716
- return new Promise((resolve34, reject) => {
494280
+ return new Promise((resolve35, reject) => {
493717
494281
  this._process = import_cross_spawn2.default(this._serverParams.command, this._serverParams.args ?? [], {
493718
494282
  env: {
493719
494283
  ...getDefaultEnvironment(),
@@ -493729,7 +494293,7 @@ class StdioClientTransport {
493729
494293
  this.onerror?.(error54);
493730
494294
  });
493731
494295
  this._process.on("spawn", () => {
493732
- resolve34();
494296
+ resolve35();
493733
494297
  });
493734
494298
  this._process.on("close", (_code) => {
493735
494299
  this._process = undefined;
@@ -493781,20 +494345,20 @@ class StdioClientTransport {
493781
494345
  if (this._process) {
493782
494346
  const processToClose = this._process;
493783
494347
  this._process = undefined;
493784
- const closePromise = new Promise((resolve34) => {
494348
+ const closePromise = new Promise((resolve35) => {
493785
494349
  processToClose.once("close", () => {
493786
- resolve34();
494350
+ resolve35();
493787
494351
  });
493788
494352
  });
493789
494353
  try {
493790
494354
  processToClose.stdin?.end();
493791
494355
  } catch {}
493792
- await Promise.race([closePromise, new Promise((resolve34) => setTimeout(resolve34, 2000).unref())]);
494356
+ await Promise.race([closePromise, new Promise((resolve35) => setTimeout(resolve35, 2000).unref())]);
493793
494357
  if (processToClose.exitCode === null) {
493794
494358
  try {
493795
494359
  processToClose.kill("SIGTERM");
493796
494360
  } catch {}
493797
- await Promise.race([closePromise, new Promise((resolve34) => setTimeout(resolve34, 2000).unref())]);
494361
+ await Promise.race([closePromise, new Promise((resolve35) => setTimeout(resolve35, 2000).unref())]);
493798
494362
  }
493799
494363
  if (processToClose.exitCode === null) {
493800
494364
  try {
@@ -493805,15 +494369,15 @@ class StdioClientTransport {
493805
494369
  this._readBuffer.clear();
493806
494370
  }
493807
494371
  send(message) {
493808
- return new Promise((resolve34) => {
494372
+ return new Promise((resolve35) => {
493809
494373
  if (!this._process?.stdin) {
493810
494374
  throw new Error("Not connected");
493811
494375
  }
493812
494376
  const json3 = serializeMessage(message);
493813
494377
  if (this._process.stdin.write(json3)) {
493814
- resolve34();
494378
+ resolve35();
493815
494379
  } else {
493816
- this._process.stdin.once("drain", resolve34);
494380
+ this._process.stdin.once("drain", resolve35);
493817
494381
  }
493818
494382
  });
493819
494383
  }
@@ -494489,7 +495053,7 @@ var init_mcp_client = __esm(() => {
494489
495053
  init_streamableHttp();
494490
495054
  DEFAULT_CLIENT_INFO = {
494491
495055
  name: "letta-code",
494492
- version: "0.30.18"
495056
+ version: "0.30.19"
494493
495057
  };
494494
495058
  });
494495
495059
 
@@ -494634,10 +495198,10 @@ async function startOAuthCallbackServerOnPort(port) {
494634
495198
  let completed = false;
494635
495199
  let settle;
494636
495200
  let reject;
494637
- const codePromise = new Promise((resolve34, rejectPromise) => {
495201
+ const codePromise = new Promise((resolve35, rejectPromise) => {
494638
495202
  settle = (code2) => {
494639
495203
  completed = true;
494640
- resolve34(code2);
495204
+ resolve35(code2);
494641
495205
  };
494642
495206
  reject = (error54) => {
494643
495207
  completed = true;
@@ -494647,8 +495211,8 @@ async function startOAuthCallbackServerOnPort(port) {
494647
495211
  codePromise.catch(() => {
494648
495212
  return;
494649
495213
  });
494650
- server2 = createServer3((request, response) => {
494651
- const url2 = new URL(request.url ?? "/", "http://127.0.0.1");
495214
+ server2 = createServer3((request2, response) => {
495215
+ const url2 = new URL(request2.url ?? "/", "http://127.0.0.1");
494652
495216
  if (url2.pathname !== "/callback") {
494653
495217
  response.writeHead(404).end("Not found");
494654
495218
  return;
@@ -494675,9 +495239,9 @@ async function startOAuthCallbackServerOnPort(port) {
494675
495239
  settle?.(code2);
494676
495240
  server2.close();
494677
495241
  });
494678
- await new Promise((resolve34, rejectListen) => {
495242
+ await new Promise((resolve35, rejectListen) => {
494679
495243
  server2.once("error", rejectListen);
494680
- server2.listen(port, "127.0.0.1", resolve34);
495244
+ server2.listen(port, "127.0.0.1", resolve35);
494681
495245
  });
494682
495246
  server2.unref();
494683
495247
  const address = server2.address();
@@ -494912,7 +495476,7 @@ var init_mcp_runtime = __esm(async () => {
494912
495476
 
494913
495477
  // src/skills/builtin/creating-skills/scripts/validate-skill.ts
494914
495478
  import { existsSync as existsSync61, readFileSync as readFileSync40 } from "node:fs";
494915
- import { basename as basename30, join as join79, resolve as resolve34 } from "node:path";
495479
+ import { basename as basename31, join as join79, resolve as resolve35 } from "node:path";
494916
495480
  import { fileURLToPath as fileURLToPath11 } from "node:url";
494917
495481
  function parseQuotedScalar(value) {
494918
495482
  if (value.startsWith('"')) {
@@ -495072,7 +495636,7 @@ function validateSkill(skillPath) {
495072
495636
  message: `Name is too long (${trimmedName.length} characters). Maximum is ${MAX_SKILL_NAME_LENGTH} characters.`
495073
495637
  };
495074
495638
  }
495075
- const dirName = basename30(skillPath);
495639
+ const dirName = basename31(skillPath);
495076
495640
  if (trimmedName !== dirName) {
495077
495641
  warnings.push(`Name '${trimmedName}' doesn't match directory name '${dirName}'. For portability, these should match.`);
495078
495642
  }
@@ -495107,7 +495671,7 @@ function validateSkill(skillPath) {
495107
495671
  }
495108
495672
  function isMainModule() {
495109
495673
  const entrypoint = process.argv[1];
495110
- return entrypoint ? resolve34(entrypoint) === fileURLToPath11(import.meta.url) : false;
495674
+ return entrypoint ? resolve35(entrypoint) === fileURLToPath11(import.meta.url) : false;
495111
495675
  }
495112
495676
  var ALLOWED_PROPERTIES, MAX_SKILL_NAME_LENGTH = 64;
495113
495677
  var init_validate_skill = __esm(() => {
@@ -495176,8 +495740,8 @@ __export(exports_import, {
495176
495740
  extractSkillsFromAf: () => extractSkillsFromAf
495177
495741
  });
495178
495742
  import { createReadStream as createReadStream2 } from "node:fs";
495179
- import { access as access2, chmod, mkdir as mkdir17, readFile as readFile29, writeFile as writeFile19 } from "node:fs/promises";
495180
- import { dirname as dirname34, isAbsolute as isAbsolute28, relative as relative14, resolve as resolve35, sep as sep8, win32 as win325 } from "node:path";
495743
+ import { access as access2, chmod, mkdir as mkdir17, readFile as readFile30, writeFile as writeFile20 } from "node:fs/promises";
495744
+ import { dirname as dirname34, isAbsolute as isAbsolute28, relative as relative14, resolve as resolve36, sep as sep8, win32 as win325 } from "node:path";
495181
495745
  function validateImportedSkillName(name) {
495182
495746
  const trimmedName = name.trim();
495183
495747
  if (trimmedName !== name || trimmedName.length === 0 || trimmedName.length > MAX_SKILL_NAME_LENGTH || trimmedName === "." || trimmedName === ".." || !IMPORTED_SKILL_NAME_PATTERN.test(trimmedName)) {
@@ -495186,8 +495750,8 @@ function validateImportedSkillName(name) {
495186
495750
  return trimmedName;
495187
495751
  }
495188
495752
  function assertPathInside(parent, child) {
495189
- const parentPath = resolve35(parent);
495190
- const childPath = resolve35(child);
495753
+ const parentPath = resolve36(parent);
495754
+ const childPath = resolve36(child);
495191
495755
  const relativePath = relative14(parentPath, childPath);
495192
495756
  if (relativePath === "" || relativePath === ".." || relativePath.startsWith(`..${sep8}`) || isAbsolute28(relativePath)) {
495193
495757
  throw new Error(`Imported skill file path escapes skill directory: ${child}`);
@@ -495205,7 +495769,7 @@ function validateImportedSkillFilePath(filePath) {
495205
495769
  }
495206
495770
  function resolveImportedSkillFilePath(skillDir, filePath) {
495207
495771
  const safeFilePath = validateImportedSkillFilePath(filePath);
495208
- const fullPath = resolve35(skillDir, safeFilePath);
495772
+ const fullPath = resolve36(skillDir, safeFilePath);
495209
495773
  assertPathInside(skillDir, fullPath);
495210
495774
  return fullPath;
495211
495775
  }
@@ -495239,7 +495803,7 @@ async function importAgentFromFile(options3) {
495239
495803
  if (!getBackend().capabilities.agentFileImportExport) {
495240
495804
  throw new Error("Agent file import is not supported by this backend yet");
495241
495805
  }
495242
- const resolvedPath = resolve35(options3.filePath);
495806
+ const resolvedPath = resolve36(options3.filePath);
495243
495807
  try {
495244
495808
  await access2(resolvedPath);
495245
495809
  } catch {
@@ -495277,14 +495841,14 @@ async function importAgentFromFile(options3) {
495277
495841
  }
495278
495842
  async function extractSkillsFromAf(afPath, destDir) {
495279
495843
  const extracted = [];
495280
- const content = await readFile29(afPath, "utf-8");
495844
+ const content = await readFile30(afPath, "utf-8");
495281
495845
  const afData = JSON.parse(content);
495282
495846
  if (!afData.skills || !Array.isArray(afData.skills)) {
495283
495847
  return [];
495284
495848
  }
495285
495849
  for (const skill2 of afData.skills) {
495286
495850
  const skillName = validateImportedSkillName(skill2.name);
495287
- const skillDir = resolve35(destDir, skillName);
495851
+ const skillDir = resolve36(destDir, skillName);
495288
495852
  await mkdir17(skillDir, { recursive: true });
495289
495853
  if (skill2.files) {
495290
495854
  await writeSkillFiles(skillDir, skill2.files);
@@ -495306,7 +495870,7 @@ async function writeSkillFiles(skillDir, files) {
495306
495870
  async function writeSkillFile(skillDir, filePath, content) {
495307
495871
  const fullPath = resolveImportedSkillFilePath(skillDir, filePath);
495308
495872
  await mkdir17(dirname34(fullPath), { recursive: true });
495309
- await writeFile19(fullPath, content, "utf-8");
495873
+ await writeFile20(fullPath, content, "utf-8");
495310
495874
  const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
495311
495875
  if (isScript) {
495312
495876
  try {
@@ -495359,7 +495923,7 @@ function parseRegistryHandle(handle2) {
495359
495923
  async function importAgentFromRegistry(options3) {
495360
495924
  const { tmpdir: tmpdir11 } = await import("node:os");
495361
495925
  const { join: join80 } = await import("node:path");
495362
- const { writeFile: writeFile20, unlink: unlink6 } = await import("node:fs/promises");
495926
+ const { writeFile: writeFile21, unlink: unlink6 } = await import("node:fs/promises");
495363
495927
  const { author, name } = parseRegistryHandle(options3.handle);
495364
495928
  const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER}/${AGENT_REGISTRY_REPO}/refs/heads/${AGENT_REGISTRY_BRANCH}/agents/@${author}/${name}/${name}.af`;
495365
495929
  const response = await fetch(rawUrl);
@@ -495371,7 +495935,7 @@ async function importAgentFromRegistry(options3) {
495371
495935
  }
495372
495936
  const afContent = await response.text();
495373
495937
  const tempPath = join80(tmpdir11(), `letta-import-${author}-${name}-${Date.now()}.af`);
495374
- await writeFile20(tempPath, afContent, "utf-8");
495938
+ await writeFile21(tempPath, afContent, "utf-8");
495375
495939
  try {
495376
495940
  const result = await importAgentFromFile({
495377
495941
  filePath: tempPath,
@@ -495784,10 +496348,10 @@ async function sendScopedApprovalMessages(params) {
495784
496348
  });
495785
496349
  }
495786
496350
  async function flushAndExit(code2) {
495787
- const flushWritable = (stream12) => new Promise((resolve36) => {
496351
+ const flushWritable = (stream12) => new Promise((resolve37) => {
495788
496352
  if (stream12.destroyed || stream12.writableEnded)
495789
- return resolve36();
495790
- stream12.write("", () => resolve36());
496353
+ return resolve37();
496354
+ stream12.write("", () => resolve37());
495791
496355
  });
495792
496356
  await closeClientMcpServers();
495793
496357
  await Promise.allSettled([
@@ -495797,12 +496361,12 @@ async function flushAndExit(code2) {
495797
496361
  process.exit(code2);
495798
496362
  }
495799
496363
  async function writeFinalHeadlessStdout(text2) {
495800
- await new Promise((resolve36) => {
496364
+ await new Promise((resolve37) => {
495801
496365
  if (process.stdout.destroyed || process.stdout.writableEnded) {
495802
- resolve36();
496366
+ resolve37();
495803
496367
  return;
495804
496368
  }
495805
- process.stdout.write(text2, () => resolve36());
496369
+ process.stdout.write(text2, () => resolve37());
495806
496370
  });
495807
496371
  }
495808
496372
  function pageItems5(page) {
@@ -495895,7 +496459,7 @@ async function waitForEnvironmentAssistantMessage(params) {
495895
496459
  return { text: text2, stopReason: observedStopReason };
495896
496460
  }
495897
496461
  }
495898
- await new Promise((resolve36) => setTimeout(resolve36, pollIntervalMs));
496462
+ await new Promise((resolve37) => setTimeout(resolve37, pollIntervalMs));
495899
496463
  }
495900
496464
  if (observedCompletion && lastText) {
495901
496465
  return { text: lastText, stopReason: observedStopReason };
@@ -496813,7 +497377,7 @@ ${loadedContents.join(`
496813
497377
  if (usesRemoteEnvironment) {
496814
497378
  const environmentSelector = String(explicitEnvironmentSelector);
496815
497379
  const useCloudSandbox = isCloudEnvironmentSelector(environmentSelector);
496816
- const environmentRouting = useCloudSandbox ? await resolveAgentSandboxConnectionId(agent2.id) : await resolveEnvironmentConnectionId(environmentSelector);
497380
+ const environmentRouting = useCloudSandbox ? await resolveAgentSandboxConnectionId(agent2.id, { conversationId }) : await resolveEnvironmentConnectionId(environmentSelector);
496817
497381
  const { connectionId, environment: environment2 } = environmentRouting;
496818
497382
  const responseEnvironment = buildEnvironmentResponseMetadata({
496819
497383
  source: useCloudSandbox ? "cloud-sandbox" : "explicit",
@@ -497122,7 +497686,7 @@ ${loadedContents.join(`
497122
497686
  } else {
497123
497687
  console.error(`Conversation is busy, waiting ${Math.round(retryDelayMs / 1000)}s and retrying...`);
497124
497688
  }
497125
- await new Promise((resolve36) => setTimeout(resolve36, retryDelayMs));
497689
+ await new Promise((resolve37) => setTimeout(resolve37, retryDelayMs));
497126
497690
  continue;
497127
497691
  }
497128
497692
  }
@@ -497171,7 +497735,7 @@ ${loadedContents.join(`
497171
497735
  const delaySeconds = Math.round(delayMs / 1000);
497172
497736
  console.error(`Transient API error before streaming (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
497173
497737
  }
497174
- await new Promise((resolve36) => setTimeout(resolve36, delayMs));
497738
+ await new Promise((resolve37) => setTimeout(resolve37, delayMs));
497175
497739
  conversationBusyRetries = 0;
497176
497740
  continue;
497177
497741
  }
@@ -497413,7 +497977,7 @@ ${loadedContents.join(`
497413
497977
  const delaySeconds = Math.round(delayMs / 1000);
497414
497978
  console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
497415
497979
  }
497416
- await new Promise((resolve36) => setTimeout(resolve36, delayMs));
497980
+ await new Promise((resolve37) => setTimeout(resolve37, delayMs));
497417
497981
  currentInput = refreshInputOtidsForNewRequest(currentInput);
497418
497982
  continue;
497419
497983
  }
@@ -497505,7 +498069,7 @@ ${loadedContents.join(`
497505
498069
  } else {
497506
498070
  console.error(`Empty LLM response, retrying (attempt ${attempt} of ${EMPTY_RESPONSE_MAX_RETRIES2})...`);
497507
498071
  }
497508
- await new Promise((resolve36) => setTimeout(resolve36, delayMs));
498072
+ await new Promise((resolve37) => setTimeout(resolve37, delayMs));
497509
498073
  currentInput = refreshInputOtidsForNewRequest(currentInput);
497510
498074
  continue;
497511
498075
  }
@@ -497533,7 +498097,7 @@ ${loadedContents.join(`
497533
498097
  const delaySeconds = Math.round(delayMs / 1000);
497534
498098
  console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
497535
498099
  }
497536
- await new Promise((resolve36) => setTimeout(resolve36, delayMs));
498100
+ await new Promise((resolve37) => setTimeout(resolve37, delayMs));
497537
498101
  currentInput = refreshInputOtidsForNewRequest(currentInput);
497538
498102
  continue;
497539
498103
  }
@@ -497563,7 +498127,7 @@ ${loadedContents.join(`
497563
498127
  const delaySeconds = Math.round(delayMs / 1000);
497564
498128
  console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
497565
498129
  }
497566
- await new Promise((resolve36) => setTimeout(resolve36, delayMs));
498130
+ await new Promise((resolve37) => setTimeout(resolve37, delayMs));
497567
498131
  currentInput = refreshInputOtidsForNewRequest(currentInput);
497568
498132
  continue;
497569
498133
  }
@@ -497572,7 +498136,7 @@ ${loadedContents.join(`
497572
498136
  markIncompleteToolsAsCancelled(buffers, true, "stream_error");
497573
498137
  const errorLines = toLines(buffers).filter((line) => line.kind === "error");
497574
498138
  const errorMessages2 = errorLines.map((line) => ("text" in line) ? line.text : "").filter(Boolean);
497575
- let errorMessage2 = errorMessages2.length > 0 ? errorMessages2.join("; ") : fallbackError || `Unexpected stop reason: ${stopReason}`;
498139
+ let errorMessage3 = errorMessages2.length > 0 ? errorMessages2.join("; ") : fallbackError || `Unexpected stop reason: ${stopReason}`;
497576
498140
  let finalRun = null;
497577
498141
  if (lastRunId) {
497578
498142
  try {
@@ -497585,10 +498149,10 @@ ${loadedContents.join(`
497585
498149
  run_id: lastRunId
497586
498150
  }
497587
498151
  };
497588
- errorMessage2 = formatErrorDetails2(errorObject, agent2.id);
498152
+ errorMessage3 = formatErrorDetails2(errorObject, agent2.id);
497589
498153
  }
497590
498154
  } catch (_e) {
497591
- errorMessage2 = `${errorMessage2}
498155
+ errorMessage3 = `${errorMessage3}
497592
498156
  (Unable to fetch additional error details from server)`;
497593
498157
  }
497594
498158
  }
@@ -497597,11 +498161,11 @@ ${loadedContents.join(`
497597
498161
  await backend3.cancelRun(finalRun.agent_id || agent2.id, lastRunId);
497598
498162
  } catch {}
497599
498163
  }
497600
- trackHeadlessBoundaryError("headless_turn_failed", errorMessage2, "headless_turn_execution");
498164
+ trackHeadlessBoundaryError("headless_turn_failed", errorMessage3, "headless_turn_execution");
497601
498165
  if (outputFormat === "stream-json") {
497602
498166
  const errorMsg = {
497603
498167
  type: "error",
497604
- message: errorMessage2,
498168
+ message: errorMessage3,
497605
498169
  stop_reason: stopReason,
497606
498170
  run_id: lastRunId ?? undefined,
497607
498171
  session_id: sessionId,
@@ -497609,7 +498173,7 @@ ${loadedContents.join(`
497609
498173
  };
497610
498174
  await writeWireMessageAsync(errorMsg);
497611
498175
  } else {
497612
- console.error(`Error: ${errorMessage2}`);
498176
+ console.error(`Error: ${errorMessage3}`);
497613
498177
  }
497614
498178
  await exitHeadless(1, "headless_stop_reason_error");
497615
498179
  }
@@ -497958,9 +498522,9 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
497958
498522
  const syntheticUserLine = serializeQueuedMessageAsUserLine(queuedMessage);
497959
498523
  maybeNotifyBlocked(syntheticUserLine);
497960
498524
  if (lineResolver) {
497961
- const resolve36 = lineResolver;
498525
+ const resolve37 = lineResolver;
497962
498526
  lineResolver = null;
497963
- resolve36(syntheticUserLine);
498527
+ resolve37(syntheticUserLine);
497964
498528
  return;
497965
498529
  }
497966
498530
  lineQueue.push(syntheticUserLine);
@@ -497980,9 +498544,9 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
497980
498544
  if (action3 === "abort-active") {
497981
498545
  currentAbortController.abort();
497982
498546
  if (lineResolver) {
497983
- const resolve36 = lineResolver;
498547
+ const resolve37 = lineResolver;
497984
498548
  lineResolver = null;
497985
- resolve36(null);
498549
+ resolve37(null);
497986
498550
  }
497987
498551
  } else if (action3 === "latch") {
497988
498552
  pendingInterrupt = true;
@@ -498002,9 +498566,9 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498002
498566
  if (lineResolver) {
498003
498567
  if (parsedLine?.type === "user")
498004
498568
  turnStarting = true;
498005
- const resolve36 = lineResolver;
498569
+ const resolve37 = lineResolver;
498006
498570
  lineResolver = null;
498007
- resolve36(line);
498571
+ resolve37(line);
498008
498572
  } else {
498009
498573
  lineQueue.push(line);
498010
498574
  }
@@ -498013,17 +498577,17 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498013
498577
  setMessageQueueAdder(null);
498014
498578
  msgQueueRuntime.clear("shutdown");
498015
498579
  if (lineResolver) {
498016
- const resolve36 = lineResolver;
498580
+ const resolve37 = lineResolver;
498017
498581
  lineResolver = null;
498018
- resolve36(null);
498582
+ resolve37(null);
498019
498583
  }
498020
498584
  });
498021
498585
  async function getNextLine() {
498022
498586
  if (lineQueue.length > 0) {
498023
498587
  return lineQueue.shift() ?? null;
498024
498588
  }
498025
- return new Promise((resolve36) => {
498026
- lineResolver = resolve36;
498589
+ return new Promise((resolve37) => {
498590
+ lineResolver = resolve37;
498027
498591
  });
498028
498592
  }
498029
498593
  async function requestPermission(toolCallId, toolName, toolInput) {
@@ -498085,9 +498649,9 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498085
498649
  }
498086
498650
  return result;
498087
498651
  }
498088
- async function recoverPendingApprovalsFromControlRequest(request) {
498089
- const targetAgentId = request.agent_id ?? agent2.id;
498090
- const targetConversationId = request.conversation_id ?? conversationId;
498652
+ async function recoverPendingApprovalsFromControlRequest(request2) {
498653
+ const targetAgentId = request2.agent_id ?? agent2.id;
498654
+ const targetConversationId = request2.conversation_id ?? conversationId;
498091
498655
  if (targetAgentId !== agent2.id) {
498092
498656
  throw new Error(`recover_pending_approvals agent mismatch: ${targetAgentId} != ${agent2.id}`);
498093
498657
  }
@@ -498544,7 +499108,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498544
499108
  uuid: `retry-bidir-${randomUUID34()}`
498545
499109
  };
498546
499110
  writeWireMessage(retryMsg);
498547
- await new Promise((resolve36) => setTimeout(resolve36, delayMs));
499111
+ await new Promise((resolve37) => setTimeout(resolve37, delayMs));
498548
499112
  continue;
498549
499113
  }
498550
499114
  throw preStreamError;
@@ -499255,7 +499819,7 @@ var BYTES_PER_TOKEN = 4;
499255
499819
 
499256
499820
  // src/cli/helpers/window-title-config.ts
499257
499821
  import { homedir as homedir44 } from "node:os";
499258
- import { basename as basename31, resolve as resolve36 } from "node:path";
499822
+ import { basename as basename32, resolve as resolve37 } from "node:path";
499259
499823
  function isWindowTitleField(value) {
499260
499824
  return WINDOW_TITLE_FIELDS.includes(value);
499261
499825
  }
@@ -499413,8 +499977,8 @@ function terminalTitleProjectName(data) {
499413
499977
  const directory = titleDirectory(data);
499414
499978
  if (!directory)
499415
499979
  return null;
499416
- const resolved = resolve36(directory);
499417
- const name = basename31(resolved) || formatDirectoryDisplay(resolved) || resolved;
499980
+ const resolved = resolve37(directory);
499981
+ const name = basename32(resolved) || formatDirectoryDisplay(resolved) || resolved;
499418
499982
  return truncateTerminalTitlePart(name, 24);
499419
499983
  }
499420
499984
  function titleDirectory(data) {
@@ -499423,7 +499987,7 @@ function titleDirectory(data) {
499423
499987
  function formatDirectoryDisplay(directory) {
499424
499988
  if (!directory)
499425
499989
  return null;
499426
- const resolved = resolve36(directory);
499990
+ const resolved = resolve37(directory);
499427
499991
  const home = homedir44();
499428
499992
  if (resolved === home)
499429
499993
  return "~";
@@ -500137,7 +500701,7 @@ var init_queued_message_parts = __esm(() => {
500137
500701
  // src/cli/helpers/reflection-arena-hf-upload.ts
500138
500702
  import { execFile as execFileCb5 } from "node:child_process";
500139
500703
  import { existsSync as existsSync63 } from "node:fs";
500140
- import { appendFile as appendFile2, chmod as chmod2, mkdir as mkdir18, writeFile as writeFile20 } from "node:fs/promises";
500704
+ import { appendFile as appendFile2, chmod as chmod2, mkdir as mkdir18, writeFile as writeFile21 } from "node:fs/promises";
500141
500705
  import { homedir as homedir45 } from "node:os";
500142
500706
  import { join as join81 } from "node:path";
500143
500707
  import { promisify as promisify15 } from "node:util";
@@ -500176,7 +500740,7 @@ async function runGit6(cwd2, args, env5) {
500176
500740
  }
500177
500741
  async function writeGitAskpass(repoRoot) {
500178
500742
  const askpassPath = join81(repoRoot, "hf-askpass.sh");
500179
- await writeFile20(askpassPath, [
500743
+ await writeFile21(askpassPath, [
500180
500744
  "#!/bin/sh",
500181
500745
  'case "$1" in',
500182
500746
  " *Username*) printf '%s\\n' 'hf_user' ;;",
@@ -500261,7 +500825,7 @@ var init_reflection_arena_hf_upload = __esm(() => {
500261
500825
  // src/cli/helpers/reflection-arena.ts
500262
500826
  import { execFile as execFileCb6 } from "node:child_process";
500263
500827
  import { randomInt as randomInt2, randomUUID as randomUUID35 } from "node:crypto";
500264
- import { appendFile as appendFile3, mkdir as mkdir19, readFile as readFile30, writeFile as writeFile21 } from "node:fs/promises";
500828
+ import { appendFile as appendFile3, mkdir as mkdir19, readFile as readFile31, writeFile as writeFile22 } from "node:fs/promises";
500265
500829
  import { homedir as homedir46 } from "node:os";
500266
500830
  import { join as join82 } from "node:path";
500267
500831
  import { promisify as promisify16 } from "node:util";
@@ -500325,11 +500889,11 @@ function getReflectionArenaRunPath(runId) {
500325
500889
  }
500326
500890
  async function saveReflectionArenaRun(run) {
500327
500891
  await mkdir19(getReflectionArenaRunsDir(), { recursive: true });
500328
- await writeFile21(getReflectionArenaRunPath(run.runId), `${JSON.stringify(run, null, 2)}
500892
+ await writeFile22(getReflectionArenaRunPath(run.runId), `${JSON.stringify(run, null, 2)}
500329
500893
  `, "utf-8");
500330
500894
  }
500331
500895
  async function loadReflectionArenaRun(runId) {
500332
- const raw2 = await readFile30(getReflectionArenaRunPath(runId), "utf-8");
500896
+ const raw2 = await readFile31(getReflectionArenaRunPath(runId), "utf-8");
500333
500897
  return JSON.parse(raw2);
500334
500898
  }
500335
500899
  async function updateReflectionArenaRun(runId, update2) {
@@ -500521,7 +501085,7 @@ async function appendChoiceRecord(run) {
500521
501085
  }
500522
501086
  async function readTranscriptPayloadForTelemetry(payloadPath) {
500523
501087
  try {
500524
- const transcript = await readFile30(payloadPath, "utf-8");
501088
+ const transcript = await readFile31(payloadPath, "utf-8");
500525
501089
  return {
500526
501090
  transcriptPayload: transcript.slice(0, REFLECTION_ARENA_TELEMETRY_TRANSCRIPT_MAX_CHARS),
500527
501091
  transcriptPayloadChars: transcript.length,
@@ -500787,6 +501351,7 @@ async function finalizeReflectionArenaChoice(options3) {
500787
501351
  }
500788
501352
  const discarded = [];
500789
501353
  let integration;
501354
+ let completionSuccess = false;
500790
501355
  let memoryBaseCommit = null;
500791
501356
  let memoryCandidateCommit = null;
500792
501357
  if (options3.choice !== "tie") {
@@ -500813,6 +501378,7 @@ async function finalizeReflectionArenaChoice(options3) {
500813
501378
  logRecompileFailure: (message) => debugWarn("memory", message)
500814
501379
  });
500815
501380
  integration = finalized.integration;
501381
+ completionSuccess = finalized.completionSuccess;
500816
501382
  }
500817
501383
  for (const candidate of run.candidates) {
500818
501384
  if (options3.choice !== "tie" && candidate.label === options3.choice) {
@@ -500824,7 +501390,7 @@ async function finalizeReflectionArenaChoice(options3) {
500824
501390
  knownNoChanges: candidateIsConfirmedNoOp(candidate)
500825
501391
  });
500826
501392
  }
500827
- await finalizeAutoReflectionPayload(run.agentId, run.conversationId, run.payloadPath, run.endSnapshotLine, integration ? reflectionIntegrationConsumesTranscript(integration) : false);
501393
+ await finalizeAutoReflectionCompletion(run.agentId, run.conversationId, run.payloadPath, run.endSnapshotLine, run.endMessageId, completionSuccess);
500828
501394
  const completedRun = {
500829
501395
  ...run,
500830
501396
  choice: {
@@ -500865,6 +501431,7 @@ var init_reflection_arena = __esm(() => {
500865
501431
  init_memory_worktree();
500866
501432
  init_app_urls();
500867
501433
  init_reflection_arena_hf_upload();
501434
+ init_reflection_completion();
500868
501435
  init_reflection_launcher();
500869
501436
  init_reflection_transcript();
500870
501437
  init_telemetry();
@@ -501168,8 +501735,8 @@ async function pushToMemoryRepositoryWithTimeout(agentId) {
501168
501735
  try {
501169
501736
  return await Promise.race([
501170
501737
  pushToMemoryRepository(agentId),
501171
- new Promise((resolve37) => {
501172
- timeout = setTimeout(() => resolve37("timeout"), INITIAL_PUSH_TIMEOUT_MS);
501738
+ new Promise((resolve38) => {
501739
+ timeout = setTimeout(() => resolve38("timeout"), INITIAL_PUSH_TIMEOUT_MS);
501173
501740
  })
501174
501741
  ]);
501175
501742
  } finally {
@@ -507483,11 +508050,11 @@ var init_HelpDialog = __esm(async () => {
507483
508050
 
507484
508051
  // src/hooks/writer.ts
507485
508052
  import { homedir as homedir49 } from "node:os";
507486
- import { resolve as resolve37 } from "node:path";
508053
+ import { resolve as resolve38 } from "node:path";
507487
508054
  function isProjectSettingsPathCollidingWithGlobal2(workingDirectory) {
507488
508055
  const home = process.env.HOME || homedir49();
507489
- const globalSettingsPath = resolve37(home, ".letta", "settings.json");
507490
- const projectSettingsPath = resolve37(workingDirectory, ".letta", "settings.json");
508056
+ const globalSettingsPath = resolve38(home, ".letta", "settings.json");
508057
+ const projectSettingsPath = resolve38(workingDirectory, ".letta", "settings.json");
507491
508058
  return globalSettingsPath === projectSettingsPath;
507492
508059
  }
507493
508060
  function loadHooksFromLocation(location, workingDirectory = process.cwd()) {
@@ -513781,7 +514348,7 @@ var init_InstallGithubAppFlow = __esm(async () => {
513781
514348
  const solidLine = SOLID_LINE11.repeat(Math.max(terminalWidth, 10));
513782
514349
  const [step, setStep] = import_react84.useState("checking");
513783
514350
  const [status, setStatus] = import_react84.useState("Checking GitHub CLI prerequisites...");
513784
- const [errorMessage2, setErrorMessage] = import_react84.useState("");
514351
+ const [errorMessage3, setErrorMessage] = import_react84.useState("");
513785
514352
  const [currentRepo, setCurrentRepo] = import_react84.useState(null);
513786
514353
  const [repoChoiceIndex, setRepoChoiceIndex] = import_react84.useState(0);
513787
514354
  const [repoInput, setRepoInput] = import_react84.useState("");
@@ -514349,14 +514916,14 @@ var init_InstallGithubAppFlow = __esm(async () => {
514349
514916
  color: "red",
514350
514917
  children: [
514351
514918
  "Error: ",
514352
- errorMessage2.split(`
514919
+ errorMessage3.split(`
514353
514920
  `)[0] || "Unknown error"
514354
514921
  ]
514355
514922
  }, undefined, true, undefined, this),
514356
514923
  /* @__PURE__ */ jsx_dev_runtime62.jsxDEV(Box_default, {
514357
514924
  height: 1
514358
514925
  }, undefined, false, undefined, this),
514359
- errorMessage2.split(`
514926
+ errorMessage3.split(`
514360
514927
  `).slice(1).filter((line) => line.trim().length > 0).map((line, idx) => /* @__PURE__ */ jsx_dev_runtime62.jsxDEV(Text2, {
514361
514928
  dimColor: true,
514362
514929
  children: line
@@ -518766,14 +519333,14 @@ function MessageSearch({
518766
519333
  resultsCache.current.set(cacheKey, emptyResults);
518767
519334
  return emptyResults;
518768
519335
  }
518769
- const request = fetchSearchResults(query2, mode, range3).then((searchResults) => {
519336
+ const request2 = fetchSearchResults(query2, mode, range3).then((searchResults) => {
518770
519337
  resultsCache.current.set(cacheKey, searchResults);
518771
519338
  return searchResults;
518772
519339
  }).finally(() => {
518773
519340
  pendingResultsCache.current.delete(cacheKey);
518774
519341
  });
518775
- pendingResultsCache.current.set(cacheKey, request);
518776
- return request;
519342
+ pendingResultsCache.current.set(cacheKey, request2);
519343
+ return request2;
518777
519344
  }, [agentId, conversationId, fetchSearchResults, getCacheKey]);
518778
519345
  const prefetchSearchResults = import_react89.useCallback((query2, mode, range3) => {
518779
519346
  const { prefetch } = buildSearchTargetPlan(mode, range3, {
@@ -520170,7 +520737,7 @@ var init_PersonalitySelector = __esm(async () => {
520170
520737
  });
520171
520738
 
520172
520739
  // src/utils/aws-credentials.ts
520173
- import { readFile as readFile31 } from "node:fs/promises";
520740
+ import { readFile as readFile32 } from "node:fs/promises";
520174
520741
  import { homedir as homedir51 } from "node:os";
520175
520742
  import { join as join88 } from "node:path";
520176
520743
  async function parseAwsCredentials() {
@@ -520178,11 +520745,11 @@ async function parseAwsCredentials() {
520178
520745
  const configPath = join88(homedir51(), ".aws", "config");
520179
520746
  const profiles = new Map;
520180
520747
  try {
520181
- const content = await readFile31(credentialsPath, "utf-8");
520748
+ const content = await readFile32(credentialsPath, "utf-8");
520182
520749
  parseIniFile(content, profiles, false);
520183
520750
  } catch {}
520184
520751
  try {
520185
- const content = await readFile31(configPath, "utf-8");
520752
+ const content = await readFile32(configPath, "utf-8");
520186
520753
  parseIniFile(content, profiles, true);
520187
520754
  } catch {}
520188
520755
  return Array.from(profiles.values());
@@ -524344,7 +524911,7 @@ var init_ToolCallMessageRich = __esm(async () => {
524344
524911
  let shellSemanticKind = null;
524345
524912
  let hasShellDescription = false;
524346
524913
  if (!isQuestionTool(rawName)) {
524347
- const parseArgs18 = () => {
524914
+ const parseArgs19 = () => {
524348
524915
  if (!argsText.trim()) {
524349
524916
  return { formatted: null, parseable: true };
524350
524917
  }
@@ -524358,7 +524925,7 @@ var init_ToolCallMessageRich = __esm(async () => {
524358
524925
  return { formatted: null, parseable: false };
524359
524926
  }
524360
524927
  };
524361
- const { formatted, parseable } = parseArgs18();
524928
+ const { formatted, parseable } = parseArgs19();
524362
524929
  const argsComplete = parseable || line.phase === "running" || line.phase === "finished" || !isStreaming;
524363
524930
  if (!argsComplete) {
524364
524931
  args = "(…)";
@@ -526574,7 +527141,7 @@ function updateCommandResult(buffersRef, refreshDerived, cmdId, input, output, s
526574
527141
  buffersRef.current.byId.set(cmdId, line);
526575
527142
  refreshDerived();
526576
527143
  }
526577
- function parseArgs18(msg) {
527144
+ function parseArgs19(msg) {
526578
527145
  return msg.trim().split(/\s+/).filter(Boolean);
526579
527146
  }
526580
527147
  function formatConnectUsage() {
@@ -526930,7 +527497,7 @@ ${formatBedrockUsage2()}`, false);
526930
527497
  }
526931
527498
  }
526932
527499
  async function handleConnect(ctx, msg) {
526933
- const parts = parseArgs18(msg);
527500
+ const parts = parseArgs19(msg);
526934
527501
  const providerToken = parts[1];
526935
527502
  if (!providerToken) {
526936
527503
  addCommandResult(ctx.buffersRef, ctx.refreshDerived, msg, formatConnectUsage(), false);
@@ -536772,13 +537339,13 @@ var init_cleanLastNewline = () => {};
536772
537339
  function processLine(node, line, state) {
536773
537340
  const lineInfo = typeof state.lineInfo === "function" ? state.lineInfo(line) : state.lineInfo[line - 1];
536774
537341
  if (lineInfo == null) {
536775
- const errorMessage2 = `processLine: line ${line}, contains no state.lineInfo`;
536776
- console.error(errorMessage2, {
537342
+ const errorMessage3 = `processLine: line ${line}, contains no state.lineInfo`;
537343
+ console.error(errorMessage3, {
536777
537344
  node,
536778
537345
  line,
536779
537346
  state
536780
537347
  });
536781
- throw new Error(errorMessage2);
537348
+ throw new Error(errorMessage3);
536782
537349
  }
536783
537350
  node.tagName = "div";
536784
537351
  node.properties["data-line"] = lineInfo.lineNumber;
@@ -540250,9 +540817,9 @@ var instanceId = -1, DiffHunksRenderer = class {
540250
540817
  let deletionLineContent = deletionLine != null ? deletionLines[deletionLine.lineIndex] : undefined;
540251
540818
  let additionLineContent = additionLine != null ? additionLines[additionLine.lineIndex] : undefined;
540252
540819
  if (deletionLineContent == null && additionLineContent == null) {
540253
- const errorMessage2 = "DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong";
540254
- console.error(errorMessage2, { file: fileDiff.name });
540255
- throw new Error(errorMessage2);
540820
+ const errorMessage3 = "DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong";
540821
+ console.error(errorMessage3, { file: fileDiff.name });
540822
+ throw new Error(errorMessage3);
540256
540823
  }
540257
540824
  const lineType = type3 === "change" ? additionLine != null ? "change-addition" : "change-deletion" : type3;
540258
540825
  const lineDecoration = this.getUnifiedLineDecoration({
@@ -540294,9 +540861,9 @@ var instanceId = -1, DiffHunksRenderer = class {
540294
540861
  lineIndex: additionLine?.lineIndex
540295
540862
  });
540296
540863
  if (deletionLineContent == null && additionLineContent == null) {
540297
- const errorMessage2 = "DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong";
540298
- console.error(errorMessage2, { file: fileDiff.name });
540299
- throw new Error(errorMessage2);
540864
+ const errorMessage3 = "DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong";
540865
+ console.error(errorMessage3, { file: fileDiff.name });
540866
+ throw new Error(errorMessage3);
540300
540867
  }
540301
540868
  const missingSide = (() => {
540302
540869
  if (type3 === "change") {
@@ -541289,7 +541856,7 @@ __export(exports_generate_diff_viewer, {
541289
541856
  import { execFile as execFileCb8 } from "node:child_process";
541290
541857
  import { chmodSync as chmodSync8, existsSync as existsSync68, mkdirSync as mkdirSync48, writeFileSync as writeFileSync38 } from "node:fs";
541291
541858
  import { homedir as homedir52 } from "node:os";
541292
- import { isAbsolute as isAbsolute29, join as join89, resolve as resolve38 } from "node:path";
541859
+ import { isAbsolute as isAbsolute29, join as join89, resolve as resolve39 } from "node:path";
541293
541860
  import { promisify as promisify18 } from "node:util";
541294
541861
  async function runGit8(cwd2, args) {
541295
541862
  try {
@@ -541487,7 +542054,7 @@ function escapeHtml3(value) {
541487
542054
  function resolveTargetPath(targetPath) {
541488
542055
  if (!targetPath?.trim())
541489
542056
  return process.cwd();
541490
- return isAbsolute29(targetPath) ? targetPath : resolve38(process.cwd(), targetPath);
542057
+ return isAbsolute29(targetPath) ? targetPath : resolve39(process.cwd(), targetPath);
541491
542058
  }
541492
542059
  function shouldSkipOpen() {
541493
542060
  return Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
@@ -544771,7 +545338,7 @@ var init_system_reminders = __esm(() => {
544771
545338
  // src/cli/app/use-conversation-loop.ts
544772
545339
  import { randomUUID as randomUUID38 } from "node:crypto";
544773
545340
  function sleep10(ms) {
544774
- return new Promise((resolve39) => setTimeout(resolve39, ms));
545341
+ return new Promise((resolve40) => setTimeout(resolve40, ms));
544775
545342
  }
544776
545343
  function makeExecutionPhaseHook(setExecutionPhase) {
544777
545344
  return ({ chunk }) => {
@@ -545222,7 +545789,7 @@ function useConversationLoop(ctx) {
545222
545789
  cancelled = true;
545223
545790
  break;
545224
545791
  }
545225
- await new Promise((resolve39) => setTimeout(resolve39, 100));
545792
+ await new Promise((resolve40) => setTimeout(resolve40, 100));
545226
545793
  }
545227
545794
  buffersRef.current.byId.delete(statusId);
545228
545795
  buffersRef.current.order = buffersRef.current.order.filter((id2) => id2 !== statusId);
@@ -545286,7 +545853,7 @@ function useConversationLoop(ctx) {
545286
545853
  cancelled = true;
545287
545854
  break;
545288
545855
  }
545289
- await new Promise((resolve39) => setTimeout(resolve39, 100));
545856
+ await new Promise((resolve40) => setTimeout(resolve40, 100));
545290
545857
  }
545291
545858
  if (retryStatusId) {
545292
545859
  buffersRef.current.byId.delete(retryStatusId);
@@ -546080,7 +546647,7 @@ ${feedback}
546080
546647
  });
546081
546648
  buffersRef.current.order.push(statusId);
546082
546649
  refreshDerived();
546083
- await new Promise((resolve39) => setTimeout(resolve39, delayMs));
546650
+ await new Promise((resolve40) => setTimeout(resolve40, delayMs));
546084
546651
  buffersRef.current.byId.delete(statusId);
546085
546652
  buffersRef.current.order = buffersRef.current.order.filter((id2) => id2 !== statusId);
546086
546653
  refreshDerived();
@@ -546140,7 +546707,7 @@ ${feedback}
546140
546707
  cancelled = true;
546141
546708
  break;
546142
546709
  }
546143
- await new Promise((resolve39) => setTimeout(resolve39, 100));
546710
+ await new Promise((resolve40) => setTimeout(resolve40, 100));
546144
546711
  }
546145
546712
  if (retryStatusId) {
546146
546713
  buffersRef.current.byId.delete(retryStatusId);
@@ -547876,7 +548443,7 @@ The deployment target for this project is CITATION-DOGFOOD-OK.
547876
548443
 
547877
548444
  // src/mods/learning-harness.ts
547878
548445
  import { spawn as spawn13 } from "node:child_process";
547879
- import { access as access3, copyFile as copyFile2, mkdir as mkdir20, readFile as readFile32, writeFile as writeFile22 } from "node:fs/promises";
548446
+ import { access as access3, copyFile as copyFile2, mkdir as mkdir20, readFile as readFile33, writeFile as writeFile23 } from "node:fs/promises";
547880
548447
  import path47 from "node:path";
547881
548448
  function slugify2(value) {
547882
548449
  const slug = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
@@ -548124,14 +548691,14 @@ async function existingPath(filePath) {
548124
548691
  return await fileExists(filePath) ? filePath : undefined;
548125
548692
  }
548126
548693
  async function writeJsonArtifact(filePath, value) {
548127
- await writeFile22(filePath, `${JSON.stringify(value, null, 2)}
548694
+ await writeFile23(filePath, `${JSON.stringify(value, null, 2)}
548128
548695
  `, "utf8");
548129
548696
  }
548130
548697
  async function writeCommandArtifacts(prefix, command, args, result) {
548131
- await writeFile22(`${prefix}.command.txt`, `${renderCommand(command, args)}
548698
+ await writeFile23(`${prefix}.command.txt`, `${renderCommand(command, args)}
548132
548699
  `, "utf8");
548133
- await writeFile22(`${prefix}.stdout`, result.stdout, "utf8");
548134
- await writeFile22(`${prefix}.stderr`, result.stderr, "utf8");
548700
+ await writeFile23(`${prefix}.stdout`, result.stdout, "utf8");
548701
+ await writeFile23(`${prefix}.stderr`, result.stderr, "utf8");
548135
548702
  await writeJsonArtifact(`${prefix}.result.json`, result);
548136
548703
  }
548137
548704
  async function prepareMemoryFiles(memoryDir, memoryFiles) {
@@ -548139,7 +548706,7 @@ async function prepareMemoryFiles(memoryDir, memoryFiles) {
548139
548706
  for (const [relativePath, content] of Object.entries(memoryFiles ?? {})) {
548140
548707
  const filePath = safeJoin(memoryDir, relativePath);
548141
548708
  await mkdir20(path47.dirname(filePath), { recursive: true });
548142
- await writeFile22(filePath, content, "utf8");
548709
+ await writeFile23(filePath, content, "utf8");
548143
548710
  }
548144
548711
  }
548145
548712
  function renderEvaluationPrompt(prompt, memoryDir) {
@@ -548802,7 +549369,7 @@ function renderProposerGuide(params) {
548802
549369
  `;
548803
549370
  }
548804
549371
  async function writeHistoryArtifacts(params) {
548805
- await writeFile22(params.historyPath, renderHistoryIndex({
549372
+ await writeFile23(params.historyPath, renderHistoryIndex({
548806
549373
  attempts: params.attempts,
548807
549374
  historyManifestPath: params.historyManifestPath,
548808
549375
  proposerGuidePath: params.proposerGuidePath,
@@ -548810,11 +549377,11 @@ async function writeHistoryArtifacts(params) {
548810
549377
  spec: params.spec
548811
549378
  }), "utf8");
548812
549379
  await writeJsonArtifact(params.historyManifestPath, buildHistoryManifest(params));
548813
- await writeFile22(params.proposerGuidePath, renderProposerGuide(params), "utf8");
549380
+ await writeFile23(params.proposerGuidePath, renderProposerGuide(params), "utf8");
548814
549381
  }
548815
549382
  async function defaultCommandRunner(command, args, options3) {
548816
549383
  const startedAt = Date.now();
548817
- return new Promise((resolve39) => {
549384
+ return new Promise((resolve40) => {
548818
549385
  const child = spawn13(command, args, {
548819
549386
  cwd: options3.cwd,
548820
549387
  env: options3.env,
@@ -548841,7 +549408,7 @@ async function defaultCommandRunner(command, args, options3) {
548841
549408
  });
548842
549409
  child.on("close", (exitCode) => {
548843
549410
  clearTimeout(timeout);
548844
- resolve39({
549411
+ resolve40({
548845
549412
  args,
548846
549413
  command,
548847
549414
  cwd: options3.cwd,
@@ -548901,7 +549468,7 @@ function createScenarioSuiteEvaluator(params) {
548901
549468
  outputFormat
548902
549469
  })
548903
549470
  ];
548904
- await writeFile22(hasConfiguredScenarios ? path47.join(scenarioDir, "prompt.md") : path47.join(context3.runDir, "eval-prompt.md"), evalPrompt, "utf8");
549471
+ await writeFile23(hasConfiguredScenarios ? path47.join(scenarioDir, "prompt.md") : path47.join(context3.runDir, "eval-prompt.md"), evalPrompt, "utf8");
548905
549472
  const scenarioEvalResult = await context3.runner(context3.cliCommand, evalArgs, {
548906
549473
  cwd: context3.repoRoot,
548907
549474
  env: {
@@ -549093,7 +549660,7 @@ async function runModLearningCandidate(params) {
549093
549660
  outputFormat: "json"
549094
549661
  })
549095
549662
  ];
549096
- await writeFile22(path47.join(runDir, "generation-prompt.md"), generationPrompt, "utf8");
549663
+ await writeFile23(path47.join(runDir, "generation-prompt.md"), generationPrompt, "utf8");
549097
549664
  generationResult = await params.runner(params.cliCommand, generationArgs, {
549098
549665
  cwd: repoRoot,
549099
549666
  env: {
@@ -549172,7 +549739,7 @@ async function runModLearningCandidate(params) {
549172
549739
  spec: options3.spec
549173
549740
  };
549174
549741
  await writeJsonArtifact(path47.join(runDir, "report.json"), report);
549175
- await writeFile22(reportPath, renderMarkdownReport(report), "utf8");
549742
+ await writeFile23(reportPath, renderMarkdownReport(report), "utf8");
549176
549743
  await writeCandidateManifest(report);
549177
549744
  emitProgress("done", params.candidateCount > 1 ? `Optimization iteration ${params.candidateIndex}/${params.candidateCount} complete` : "mod optimization complete", {
549178
549745
  attempts: [...params.previousAttempts, summarizeAttempt(report)],
@@ -549350,7 +549917,7 @@ async function runModLearning(options3) {
549350
549917
  spec: normalizedOptions.spec
549351
549918
  });
549352
549919
  await writeJsonArtifact(path47.join(runDir, "report.json"), report);
549353
- await writeFile22(reportPath, renderMarkdownReport(report), "utf8");
549920
+ await writeFile23(reportPath, renderMarkdownReport(report), "utf8");
549354
549921
  normalizedOptions.onProgress?.({
549355
549922
  candidateCount,
549356
549923
  candidateIndex: selectedCandidateIndex,
@@ -549368,7 +549935,7 @@ async function runModLearning(options3) {
549368
549935
  return report;
549369
549936
  }
549370
549937
  async function readModLearningEnv(envPath) {
549371
- return JSON.parse(await readFile32(envPath, "utf8"));
549938
+ return JSON.parse(await readFile33(envPath, "utf8"));
549372
549939
  }
549373
549940
  var init_learning_harness = __esm(async () => {
549374
549941
  await init_mod_engine();
@@ -549936,7 +550503,7 @@ var init_mods2 = __esm(async () => {
549936
550503
  });
549937
550504
 
549938
550505
  // src/cli/helpers/chdir-command.ts
549939
- import { realpath as realpath5, stat as stat17 } from "node:fs/promises";
550506
+ import { realpath as realpath5, stat as stat18 } from "node:fs/promises";
549940
550507
  import { homedir as homedir54 } from "node:os";
549941
550508
  import path49 from "node:path";
549942
550509
  function parseChdirCommand(input) {
@@ -549975,7 +550542,7 @@ async function resolveChdirTarget(pathArg, currentWorkingDirectory) {
549975
550542
  const expanded = expandHome(pathArg);
549976
550543
  const resolved = path49.isAbsolute(expanded) ? expanded : path49.resolve(currentWorkingDirectory, expanded);
549977
550544
  const normalized = await realpath5(resolved);
549978
- const stats = await stat17(normalized);
550545
+ const stats = await stat18(normalized);
549979
550546
  if (!stats.isDirectory()) {
549980
550547
  throw new Error(`Not a directory: ${normalized}`);
549981
550548
  }
@@ -551619,7 +552186,7 @@ __export(exports_worktree_diff_list, {
551619
552186
  listWorktreeDiffOptions: () => listWorktreeDiffOptions
551620
552187
  });
551621
552188
  import { execFile as execFileCb9 } from "node:child_process";
551622
- import { basename as basename32 } from "node:path";
552189
+ import { basename as basename33 } from "node:path";
551623
552190
  import { promisify as promisify19 } from "node:util";
551624
552191
  async function runGit9(cwd2, args) {
551625
552192
  try {
@@ -551668,7 +552235,7 @@ function parseWorktreeList(output, currentPath) {
551668
552235
  if (current?.path) {
551669
552236
  worktrees.push({
551670
552237
  path: current.path,
551671
- name: basename32(current.path),
552238
+ name: basename33(current.path),
551672
552239
  branch: current.branch ?? "detached",
551673
552240
  head: current.head ?? "",
551674
552241
  isCurrent: current.path === currentPath,
@@ -551694,7 +552261,7 @@ function parseWorktreeList(output, currentPath) {
551694
552261
  if (current?.path) {
551695
552262
  worktrees.push({
551696
552263
  path: current.path,
551697
- name: basename32(current.path),
552264
+ name: basename33(current.path),
551698
552265
  branch: current.branch ?? "detached",
551699
552266
  head: current.head ?? "",
551700
552267
  isCurrent: current.path === currentPath,
@@ -551763,15 +552330,15 @@ var exports_export = {};
551763
552330
  __export(exports_export, {
551764
552331
  packageSkills: () => packageSkills
551765
552332
  });
551766
- import { readdir as readdir17, readFile as readFile33 } from "node:fs/promises";
551767
- import { relative as relative17, resolve as resolve39 } from "node:path";
552333
+ import { readdir as readdir17, readFile as readFile34 } from "node:fs/promises";
552334
+ import { relative as relative17, resolve as resolve40 } from "node:path";
551768
552335
  async function packageSkills(agentId, skillsDir) {
551769
552336
  const skills = [];
551770
552337
  const skillNames = new Set;
551771
552338
  const dirsToCheck = skillsDir ? [skillsDir] : [
551772
552339
  agentId && getAgentSkillsDir(agentId),
551773
- resolve39(process.cwd(), ".skills"),
551774
- resolve39(process.env.HOME || "~", ".letta", "skills")
552340
+ resolve40(process.cwd(), ".skills"),
552341
+ resolve40(process.env.HOME || "~", ".letta", "skills")
551775
552342
  ].filter((dir) => Boolean(dir));
551776
552343
  for (const baseDir of dirsToCheck) {
551777
552344
  try {
@@ -551781,10 +552348,10 @@ async function packageSkills(agentId, skillsDir) {
551781
552348
  continue;
551782
552349
  if (skillNames.has(entry.name))
551783
552350
  continue;
551784
- const skillDir = resolve39(baseDir, entry.name);
551785
- const skillMdPath = resolve39(skillDir, "SKILL.md");
552351
+ const skillDir = resolve40(baseDir, entry.name);
552352
+ const skillMdPath = resolve40(skillDir, "SKILL.md");
551786
552353
  try {
551787
- await readFile33(skillMdPath, "utf-8");
552354
+ await readFile34(skillMdPath, "utf-8");
551788
552355
  } catch {
551789
552356
  console.warn(`Skipping invalid skill ${entry.name}: missing SKILL.md`);
551790
552357
  continue;
@@ -551812,11 +552379,11 @@ async function readSkillFiles(skillDir) {
551812
552379
  async function walk(dir) {
551813
552380
  const entries = await readdir17(dir, { withFileTypes: true });
551814
552381
  for (const entry of entries) {
551815
- const fullPath = resolve39(dir, entry.name);
552382
+ const fullPath = resolve40(dir, entry.name);
551816
552383
  if (entry.isDirectory()) {
551817
552384
  await walk(fullPath);
551818
552385
  } else {
551819
- const content = await readFile33(fullPath, "utf-8");
552386
+ const content = await readFile34(fullPath, "utf-8");
551820
552387
  const relativePath = relative17(skillDir, fullPath).replace(/\\/g, "/");
551821
552388
  files[relativePath] = content;
551822
552389
  }
@@ -552470,7 +553037,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
552470
553037
  agentId,
552471
553038
  allowDisabledModelInvocation: true
552472
553039
  });
552473
- 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.";
553040
+ const request2 = 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.";
552474
553041
  cmd.finish("Running mod env generation...", true);
552475
553042
  await processConversationWithQueuedApprovals([
552476
553043
  {
@@ -552479,7 +553046,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
552479
553046
  content: buildTextParts(`${wrapSkillContent2("generating-mod-envs", skillContent)}
552480
553047
 
552481
553048
  ${SYSTEM_REMINDER_OPEN}
552482
- ${request}
553049
+ ${request2}
552483
553050
  ${SYSTEM_REMINDER_CLOSE}`),
552484
553051
  otid: randomUUID40()
552485
553052
  }
@@ -552739,7 +553306,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
552739
553306
  agentId,
552740
553307
  allowDisabledModelInvocation: true
552741
553308
  });
552742
- 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.";
553309
+ const request2 = 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.";
552743
553310
  cmd.finish("Running statusline setup...", true);
552744
553311
  await processConversationWithQueuedApprovals([
552745
553312
  {
@@ -552748,7 +553315,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
552748
553315
  content: buildTextParts(`${wrapSkillContent2("customizing-statusline", skillContent)}
552749
553316
 
552750
553317
  ${SYSTEM_REMINDER_OPEN}
552751
- ${request}
553318
+ ${request2}
552752
553319
  ${SYSTEM_REMINDER_CLOSE}`),
552753
553320
  otid: randomUUID40()
552754
553321
  }
@@ -553907,7 +554474,7 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
553907
554474
  recompileQueuedByConversation: queuedSystemPromptRecompileByConversationRef.current,
553908
554475
  logRecompileFailure: (message2) => debugWarn("memory", message2)
553909
554476
  });
553910
- await finalizeMultiReflectionPayload(agentId, autoReflectionPayload.manifest, completionSuccess);
554477
+ await finalizeMultiReflectionCompletion(agentId, autoReflectionPayload.manifest, completionSuccess);
553911
554478
  appendTaskNotificationEvents([completionMessage]);
553912
554479
  } finally {
553913
554480
  releaseReflectionReservation();
@@ -554002,7 +554569,7 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
554002
554569
  recompileQueuedByConversation: queuedSystemPromptRecompileByConversationRef.current,
554003
554570
  logRecompileFailure: (message2) => debugWarn("memory", message2)
554004
554571
  });
554005
- await finalizeMultiReflectionPayload(agentId, reflectionPayload.manifest, completionSuccess);
554572
+ await finalizeMultiReflectionCompletion(agentId, reflectionPayload.manifest, completionSuccess);
554006
554573
  appendTaskNotificationEvents([completionMessage]);
554007
554574
  } finally {
554008
554575
  releaseReflectionReservation();
@@ -554452,6 +555019,7 @@ var init_use_submit_handler = __esm(async () => {
554452
555019
  init_paste_registry();
554453
555020
  init_reasoning_tab_toggle();
554454
555021
  init_reflection_arena();
555022
+ init_reflection_completion();
554455
555023
  init_reflection_launcher();
554456
555024
  init_reflection_transcript();
554457
555025
  init_skill_name_frontmatter_repair();
@@ -558056,13 +558624,13 @@ USAGE
558056
558624
  # maintenance
558057
558625
  letta update Manually check for updates and install if available
558058
558626
  letta upgrade Alias for \`letta update\`
558059
- letta --update Alias for \`letta update\`
558060
- letta --upgrade Alias for \`letta update\`
558627
+ letta --update/--upgrade Aliases for \`letta update\`
558061
558628
  letta memory ... Memory filesystem subcommands
558062
558629
  letta agents ... Agents subcommands (JSON-only)
558063
558630
  letta environments ... List available remote environments (JSON-only)
558064
558631
  letta messages ... Messages subcommands (JSON-only)
558065
558632
  letta mods ... List and manage local mods
558633
+ letta sandbox ... Transfer files to or from the current Cloud sandbox
558066
558634
  letta server ... Run a remote environment, channels, or the App Server
558067
558635
  letta connect ... Connect providers from terminal
558068
558636
  letta backend ... Show or set the default backend
@@ -558647,9 +559215,9 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
558647
559215
  process.exit(1);
558648
559216
  }
558649
559217
  } else {
558650
- const { resolve: resolve40 } = await import("node:path");
559218
+ const { resolve: resolve41 } = await import("node:path");
558651
559219
  const { existsSync: existsSync71 } = await import("node:fs");
558652
- const resolvedPath = resolve40(fromAfFile);
559220
+ const resolvedPath = resolve41(fromAfFile);
558653
559221
  if (!existsSync71(resolvedPath)) {
558654
559222
  console.error(`Error: AgentFile not found: ${resolvedPath}`);
558655
559223
  process.exit(1);
@@ -561773,4 +562341,4 @@ function registerBunOAuthFlows() {
561773
562341
  registerBunOAuthFlows();
561774
562342
  await init_src5().then(() => exports_src2);
561775
562343
 
561776
- //# debugId=EFFF93D118B173E664756E2164756E21
562344
+ //# debugId=447A31644C59E2F264756E2164756E21