@letta-ai/letta-code 0.30.17 → 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.
Files changed (37) hide show
  1. package/dist/gateway-core.js +572 -31
  2. package/dist/gateway-core.js.map +6 -4
  3. package/dist/mcp-client.js +2 -2
  4. package/dist/mcp-client.js.map +1 -1
  5. package/dist/types/agent/message.d.ts +0 -2
  6. package/dist/types/agent/message.d.ts.map +1 -1
  7. package/dist/types/channels/control-request-coordinator.d.ts +42 -0
  8. package/dist/types/channels/control-request-coordinator.d.ts.map +1 -0
  9. package/dist/types/channels/gateway-core.d.ts +1 -0
  10. package/dist/types/channels/gateway-core.d.ts.map +1 -1
  11. package/dist/types/channels/interactive.d.ts +13 -0
  12. package/dist/types/channels/interactive.d.ts.map +1 -0
  13. package/dist/types/gateway-core.d.ts +3 -0
  14. package/dist/types/gateway-core.d.ts.map +1 -1
  15. package/dist/types/tools/impl/bash.d.ts.map +1 -1
  16. package/dist/types/tools/impl/foreground-sleep.d.ts +13 -0
  17. package/dist/types/tools/impl/foreground-sleep.d.ts.map +1 -0
  18. package/dist/types/types/app-server-protocol.d.ts +1 -0
  19. package/dist/types/types/app-server-protocol.d.ts.map +1 -1
  20. package/dist/types/types/protocol_v2.d.ts +3 -3
  21. package/dist/types/types/protocol_v2.d.ts.map +1 -1
  22. package/dist/types/types/queue-update-protocol.d.ts +5 -0
  23. package/dist/types/types/queue-update-protocol.d.ts.map +1 -0
  24. package/dist/types/types/runtime-scope.d.ts +0 -2
  25. package/dist/types/types/runtime-scope.d.ts.map +1 -1
  26. package/dist/types/websocket/listener/protocol-outbound.d.ts +5 -7
  27. package/dist/types/websocket/listener/protocol-outbound.d.ts.map +1 -1
  28. package/dist/types/websocket/listener/runtime.d.ts.map +1 -1
  29. package/dist/types/websocket/listener/scope.d.ts +0 -1
  30. package/dist/types/websocket/listener/scope.d.ts.map +1 -1
  31. package/dist/types/websocket/listener/turn-lifecycle.d.ts +0 -3
  32. package/dist/types/websocket/listener/turn-lifecycle.d.ts.map +1 -1
  33. package/dist/types/websocket/listener/types.d.ts +0 -4
  34. package/dist/types/websocket/listener/types.d.ts.map +1 -1
  35. package/letta.js +1349 -837
  36. package/package.json +1 -1
  37. package/scripts/source-file-size-baseline.json +2 -2
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.17",
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
  `;
@@ -152619,8 +152621,7 @@ function resolveRuntimeScope(runtime, params) {
152619
152621
  const resolvedConversationId = resolveScopedConversationId(runtime, params);
152620
152622
  return {
152621
152623
  agent_id: resolvedAgentId,
152622
- conversation_id: resolvedConversationId,
152623
- ...params?.super_run_id ? { super_run_id: params.super_run_id } : {}
152624
+ conversation_id: resolvedConversationId
152624
152625
  };
152625
152626
  }
152626
152627
 
@@ -152755,7 +152756,6 @@ class TurnLifecycle {
152755
152756
  #createId;
152756
152757
  #state = IDLE_STATE;
152757
152758
  #lastStopReason = null;
152758
- #superRunOwner = null;
152759
152759
  constructor(createId = () => crypto.randomUUID()) {
152760
152760
  this.#createId = createId;
152761
152761
  }
@@ -152777,9 +152777,6 @@ class TurnLifecycle {
152777
152777
  get activeRunId() {
152778
152778
  return this.#state.kind === "active" ? this.#state.runId : null;
152779
152779
  }
152780
- get superRunId() {
152781
- return this.#superRunOwner?.superRunId ?? null;
152782
- }
152783
152780
  get executingToolCallIds() {
152784
152781
  return this.#state.kind === "active" || this.#state.kind === "cancelling" ? this.#state.executingToolCallIds : [];
152785
152782
  }
@@ -152829,10 +152826,6 @@ class TurnLifecycle {
152829
152826
  id: this.#createId(),
152830
152827
  signal: abortController.signal
152831
152828
  });
152832
- this.#superRunOwner = {
152833
- leaseId: lease.id,
152834
- superRunId: options3.superRunId ?? null
152835
- };
152836
152829
  this.#state = {
152837
152830
  kind: "active",
152838
152831
  origin: options3.origin,
@@ -152859,13 +152852,6 @@ class TurnLifecycle {
152859
152852
  this.#state = { ...this.#state, loopStatus: status };
152860
152853
  return true;
152861
152854
  }
152862
- releaseSuperRunId(lease) {
152863
- if (this.#superRunOwner?.leaseId !== lease.id) {
152864
- return false;
152865
- }
152866
- this.#superRunOwner = null;
152867
- return true;
152868
- }
152869
152855
  setRunId(lease, runId) {
152870
152856
  if (this.#state.kind !== "active" || !this.isCurrent(lease)) {
152871
152857
  return false;
@@ -152897,7 +152883,6 @@ class TurnLifecycle {
152897
152883
  if (this.#state.kind !== "idle") {
152898
152884
  return false;
152899
152885
  }
152900
- this.#superRunOwner = null;
152901
152886
  this.#state = {
152902
152887
  kind: "command",
152903
152888
  loopStatus: "EXECUTING_COMMAND"
@@ -152988,7 +152973,6 @@ class TurnLifecycle {
152988
152973
  }
152989
152974
  reset(stopReason = "cancelled") {
152990
152975
  const state = this.#state;
152991
- this.#superRunOwner = null;
152992
152976
  if (state.kind === "active" || state.kind === "cancelling") {
152993
152977
  if (!state.abortController.signal.aborted) {
152994
152978
  state.abortController.abort();
@@ -153159,9 +153143,6 @@ function createConversationRuntime(listener, agentId, conversationId) {
153159
153143
  key: runtimeKey,
153160
153144
  agentId: normalizedAgentId,
153161
153145
  conversationId: normalizedConversationId,
153162
- get superRunId() {
153163
- return turnLifecycle.superRunId;
153164
- },
153165
153146
  skillSources: listener.skillSourcesByConversation.get(runtimeKey)?.slice(),
153166
153147
  activeConnectionId: null,
153167
153148
  turnLifecycle,
@@ -153593,6 +153574,53 @@ var init_worktree_ownership = __esm(() => {
153593
153574
  ]);
153594
153575
  });
153595
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
+
153596
153624
  // src/tools/impl/process_manager.ts
153597
153625
  var exports_process_manager = {};
153598
153626
  __export(exports_process_manager, {
@@ -155783,6 +155811,12 @@ Output file: ${outputFile}`
155783
155811
  status: "success"
155784
155812
  };
155785
155813
  }
155814
+ if (commandRunsForegroundSleep(command)) {
155815
+ return {
155816
+ content: [{ type: "text", text: FOREGROUND_SLEEP_BLOCKED_MESSAGE }],
155817
+ status: "error"
155818
+ };
155819
+ }
155786
155820
  const effectiveTimeout = Math.min(Math.max(timeout, 1), 600000);
155787
155821
  try {
155788
155822
  const { stdout, stderr, exitCode } = await spawnCommand(command, {
@@ -155854,6 +155888,7 @@ var init_bash = __esm(() => {
155854
155888
  init_message_queue_bridge();
155855
155889
  init_task_notifications();
155856
155890
  init_worktree_ownership();
155891
+ init_foreground_sleep();
155857
155892
  init_process_manager();
155858
155893
  init_shell_env();
155859
155894
  init_shell_launchers();
@@ -157546,7 +157581,6 @@ function notifyStreamObserversRuntimeStopped(listener) {
157546
157581
  // src/websocket/listener/protocol-outbound.ts
157547
157582
  var exports_protocol_outbound = {};
157548
157583
  __export(exports_protocol_outbound, {
157549
- scheduleQueueEmit: () => scheduleQueueEmit,
157550
157584
  isSystemReminderPart: () => isSystemReminderPart,
157551
157585
  emitSubagentStateUpdate: () => emitSubagentStateUpdate,
157552
157586
  emitSubagentStateIfOpen: () => emitSubagentStateIfOpen,
@@ -157613,8 +157647,7 @@ function getScopeForRuntime(runtime, scope) {
157613
157647
  if (runtime && "listener" in runtime) {
157614
157648
  return {
157615
157649
  agent_id: scope?.agent_id ?? runtime.agentId,
157616
- conversation_id: scope?.conversation_id ?? runtime.conversationId,
157617
- super_run_id: scope?.super_run_id ?? runtime.superRunId ?? undefined
157650
+ conversation_id: scope?.conversation_id ?? runtime.conversationId
157618
157651
  };
157619
157652
  }
157620
157653
  return scope ?? {};
@@ -157756,6 +157789,9 @@ function isStreamChannelMessage(type3) {
157756
157789
  return STREAM_CHANNEL_MESSAGE_TYPES.has(type3);
157757
157790
  }
157758
157791
  function classifyOutboundFrame(message) {
157792
+ if (message.type === "update_queue" && (message.removed?.length ?? 0) > 0) {
157793
+ return "critical";
157794
+ }
157759
157795
  return COALESCABLE_STATUS_MESSAGE_TYPES.has(message.type) ? "status" : "critical";
157760
157796
  }
157761
157797
  function emitProtocolV2Message(socket, runtime, message, scope, routing) {
@@ -157779,7 +157815,7 @@ function emitProtocolV2Message(socket, runtime, message, scope, routing) {
157779
157815
  typeLabel: message.type,
157780
157816
  frameClass,
157781
157817
  ...frameClass === "status" ? {
157782
- coalesceKey: `${message.type}:${runtimeScope.agent_id ?? ""}:${runtimeScope.conversation_id ?? ""}:${runtimeScope.super_run_id ?? ""}`
157818
+ coalesceKey: `${message.type}:${runtimeScope.agent_id ?? ""}:${runtimeScope.conversation_id ?? ""}`
157783
157819
  } : {},
157784
157820
  build: () => {
157785
157821
  const eventSeq = nextListenerConnectionEventSeq(connection, listener);
@@ -157873,7 +157909,7 @@ function emitDeviceStatusIfOpen(runtime, scope) {
157873
157909
  emitDeviceStatusUpdate(transport, runtime, scope);
157874
157910
  }
157875
157911
  }
157876
- function emitQueueUpdate(socket, runtime, scope, routing = TO_SUBSCRIBERS) {
157912
+ function emitQueueUpdate(socket, runtime, scope, routing = TO_SUBSCRIBERS, removed = []) {
157877
157913
  const listener = getListenerRuntime(runtime);
157878
157914
  if (!listener) {
157879
157915
  return;
@@ -157881,7 +157917,8 @@ function emitQueueUpdate(socket, runtime, scope, routing = TO_SUBSCRIBERS) {
157881
157917
  const resolvedScope = getScopeForRuntime(runtime, scope);
157882
157918
  const message = {
157883
157919
  type: "update_queue",
157884
- queue: buildQueueSnapshot(runtime, resolvedScope)
157920
+ queue: buildQueueSnapshot(runtime, resolvedScope),
157921
+ removed: [...removed]
157885
157922
  };
157886
157923
  emitProtocolV2Message(socket, runtime, message, resolvedScope, routing);
157887
157924
  }
@@ -157977,11 +158014,11 @@ function emitDequeuedUserMessage(socket, runtime, incoming, batch) {
157977
158014
  conversation_id: incoming.conversationId
157978
158015
  });
157979
158016
  }
157980
- function emitQueueUpdateIfOpen(runtime, scope) {
158017
+ function emitQueueUpdateIfOpen(runtime, scope, removed = []) {
157981
158018
  const listener = getListenerRuntime(runtime);
157982
158019
  const transport = listener?.transport ?? listener?.socket;
157983
158020
  if (transport && isListenerTransportOpen(transport)) {
157984
- emitQueueUpdate(transport, runtime, scope);
158021
+ emitQueueUpdate(transport, runtime, scope, TO_SUBSCRIBERS, removed);
157985
158022
  }
157986
158023
  }
157987
158024
  function emitDeviceStatusUpdateIfChanged(socket, runtime, scope, options3, routing = TO_SUBSCRIBERS) {
@@ -158057,18 +158094,6 @@ function emitSubagentStateIfOpen(runtime, scope) {
158057
158094
  emitSubagentStateUpdate(transport, runtime, scope);
158058
158095
  }
158059
158096
  }
158060
- function scheduleQueueEmit(runtime, scope) {
158061
- runtime.pendingQueueEmitScope = scope;
158062
- if (runtime.queueEmitScheduled)
158063
- return;
158064
- runtime.queueEmitScheduled = true;
158065
- queueMicrotask(() => {
158066
- runtime.queueEmitScheduled = false;
158067
- const emitScope = runtime.pendingQueueEmitScope;
158068
- runtime.pendingQueueEmitScope = undefined;
158069
- emitQueueUpdateIfOpen(runtime, emitScope);
158070
- });
158071
- }
158072
158097
  function createLifecycleMessageBase(messageType, runId) {
158073
158098
  return {
158074
158099
  id: `lifecycle-${crypto.randomUUID()}`,
@@ -181475,9 +181500,6 @@ async function sendMessageStreamWithBackend(backend, conversationId, messages, o
181475
181500
  if (opts.actingUserId) {
181476
181501
  extraHeaders["X-Letta-Acting-User-Id"] = opts.actingUserId;
181477
181502
  }
181478
- if (opts.superRunId) {
181479
- extraHeaders["X-Letta-Super-Run-Id"] = opts.superRunId;
181480
- }
181481
181503
  const messageSummary = normalizedMessages.map((item) => {
181482
181504
  if (item.type === "approval") {
181483
181505
  return `approval:${item.approvals?.length ?? 0}`;
@@ -239513,7 +239535,7 @@ var init_utils5 = __esm(() => {
239513
239535
  init_media();
239514
239536
  TELEGRAM_LIFECYCLE_ERROR_DEDUPE_TTL_MS = 6 * 60 * 60 * 1000;
239515
239537
  TELEGRAM_LIFECYCLE_ERROR_REPORT_TTL_MS = 6 * 60 * 60 * 1000;
239516
- TELEGRAM_TYPING_MAX_MS = 5 * 60 * 1000;
239538
+ TELEGRAM_TYPING_MAX_MS = 6 * 60 * 60 * 1000;
239517
239539
  });
239518
239540
 
239519
239541
  // src/channels/telegram/account-display.ts
@@ -240185,9 +240207,22 @@ async function stopTelegramBotQuietly(telegramBot, options3) {
240185
240207
  }
240186
240208
  var DEFAULT_TELEGRAM_INIT_TIMEOUT_MS = 15000, DEFAULT_TELEGRAM_START_TIMEOUT_MS = 20000, TELEGRAM_FAILED_START_STOP_TIMEOUT_MS = 5000;
240187
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
+
240188
240221
  // src/channels/telegram/typing-controller.ts
240189
240222
  function createTelegramTypingController(deps) {
240190
- const typingByChatId = new Map;
240223
+ const timers = deps.timers ?? SYSTEM_TYPING_CONTROLLER_TIMERS;
240224
+ const typingByTarget = new Map;
240225
+ const lastOutboundAtByTarget = new Map;
240191
240226
  function getChatId(source2) {
240192
240227
  if (source2.channel !== "telegram")
240193
240228
  return null;
@@ -240207,59 +240242,93 @@ function createTelegramTypingController(deps) {
240207
240242
  source2.conversationId
240208
240243
  ].join(":");
240209
240244
  }
240210
- function clearChat(chatId) {
240211
- 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);
240212
240256
  if (!entry)
240213
240257
  return;
240214
- clearInterval(entry.timer);
240215
- clearTimeout(entry.timeout);
240216
- 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?.();
240217
240270
  }
240218
240271
  function start(source2) {
240219
240272
  const chatId = getChatId(source2);
240273
+ const targetKey2 = getTargetKey(source2);
240220
240274
  const sourceKey = getSourceKey(source2);
240221
- if (!chatId || !sourceKey)
240275
+ if (!chatId || !targetKey2 || !sourceKey)
240222
240276
  return;
240223
- const existing = typingByChatId.get(chatId);
240277
+ const threadId = source2.threadId ?? null;
240278
+ const existing = typingByTarget.get(targetKey2);
240224
240279
  if (existing) {
240225
240280
  existing.sourceKeys.add(sourceKey);
240281
+ touchWatchdog(targetKey2);
240226
240282
  return;
240227
240283
  }
240228
- deps.sendTypingAction(chatId);
240229
- const timer = setInterval(() => {
240230
- 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);
240231
240290
  }, TELEGRAM_TYPING_REFRESH_MS);
240232
- const timeout = setTimeout(() => clearChat(chatId), TELEGRAM_TYPING_MAX_MS);
240291
+ const timeout = timers.setTimeout(() => clearTarget(targetKey2), TELEGRAM_TYPING_MAX_MS);
240233
240292
  timer.unref?.();
240234
240293
  timeout.unref?.();
240235
- typingByChatId.set(chatId, {
240294
+ typingByTarget.set(targetKey2, {
240236
240295
  sourceKeys: new Set([sourceKey]),
240237
240296
  timer,
240238
240297
  timeout
240239
240298
  });
240240
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
+ }
240241
240307
  function stop(source2) {
240242
- const chatId = getChatId(source2);
240308
+ const targetKey2 = getTargetKey(source2);
240243
240309
  const sourceKey = getSourceKey(source2);
240244
- if (!chatId || !sourceKey)
240310
+ if (!targetKey2 || !sourceKey)
240245
240311
  return;
240246
- const entry = typingByChatId.get(chatId);
240312
+ const entry = typingByTarget.get(targetKey2);
240247
240313
  if (!entry)
240248
240314
  return;
240249
240315
  entry.sourceKeys.delete(sourceKey);
240250
240316
  if (entry.sourceKeys.size === 0)
240251
- clearChat(chatId);
240317
+ clearTarget(targetKey2);
240252
240318
  }
240253
240319
  function clearAll() {
240254
- for (const entry of typingByChatId.values()) {
240255
- clearInterval(entry.timer);
240256
- clearTimeout(entry.timeout);
240320
+ for (const entry of typingByTarget.values()) {
240321
+ timers.clearInterval(entry.timer);
240322
+ timers.clearTimeout(entry.timeout);
240257
240323
  }
240258
- typingByChatId.clear();
240324
+ typingByTarget.clear();
240325
+ lastOutboundAtByTarget.clear();
240259
240326
  }
240260
- return { clearAll, clearChat, getChatId, start, stop };
240327
+ return { clearAll, getChatId, markOutbound, start, stop };
240261
240328
  }
240329
+ var OUTBOUND_TYPING_SUPPRESSION_MS = 1000;
240262
240330
  var init_typing_controller = __esm(() => {
240331
+ init_typing_controller_timers();
240263
240332
  init_utils5();
240264
240333
  });
240265
240334
 
@@ -240308,12 +240377,14 @@ function createTelegramAdapter(config3) {
240308
240377
  async function dispatchInbound(inbound) {
240309
240378
  await debouncer.enqueue({ inbound });
240310
240379
  }
240311
- async function sendTypingAction(chatId) {
240380
+ async function sendTypingAction(chatId, threadId) {
240312
240381
  if (!running)
240313
240382
  return;
240314
240383
  try {
240315
240384
  const telegramBot = await ensureBot();
240316
- await telegramBot.api.sendChatAction(chatId, "typing");
240385
+ await telegramBot.api.sendChatAction(chatId, "typing", {
240386
+ ...threadId ? { message_thread_id: Number(threadId) } : {}
240387
+ });
240317
240388
  } catch (error54) {
240318
240389
  console.warn(`[Telegram] Failed to send typing action for chat ${chatId}:`, error54 instanceof Error ? error54.message : error54);
240319
240390
  }
@@ -240690,7 +240761,7 @@ function createTelegramAdapter(config3) {
240690
240761
  } else {
240691
240762
  await telegramBot.api.setMessageReaction(msg.chatId, Number(targetMessageId), []);
240692
240763
  }
240693
- typing.clearChat(msg.chatId);
240764
+ typing.markOutbound(msg.chatId, resolveTelegramOutboundThreadId(msg));
240694
240765
  return { messageId: targetMessageId };
240695
240766
  }
240696
240767
  if (msg.mediaPath) {
@@ -240717,14 +240788,14 @@ function createTelegramAdapter(config3) {
240717
240788
  return await telegramBot.api.sendDocument(msg.chatId, inputFile, options3);
240718
240789
  }
240719
240790
  })();
240720
- typing.clearChat(msg.chatId);
240791
+ typing.markOutbound(msg.chatId, resolveTelegramOutboundThreadId(msg));
240721
240792
  return { messageId: String(result2.message_id) };
240722
240793
  }
240723
240794
  if (msg.richMessage) {
240724
240795
  const raw2 = telegramBot.api.raw;
240725
240796
  try {
240726
240797
  const result2 = await raw2.sendRichMessage(buildTelegramRichMessagePayload(msg));
240727
- typing.clearChat(msg.chatId);
240798
+ typing.markOutbound(msg.chatId, resolveTelegramOutboundThreadId(msg));
240728
240799
  return { messageId: String(result2.message_id) };
240729
240800
  } catch (error54) {
240730
240801
  if (!shouldFallbackTelegramRichMessage(error54)) {
@@ -240747,7 +240818,7 @@ function createTelegramAdapter(config3) {
240747
240818
  opts.parse_mode = msg.parseMode;
240748
240819
  }
240749
240820
  const result = await telegramBot.api.sendMessage(msg.chatId, msg.text, opts);
240750
- typing.clearChat(msg.chatId);
240821
+ typing.markOutbound(msg.chatId, threadId);
240751
240822
  return { messageId: String(result.message_id) };
240752
240823
  },
240753
240824
  async sendDirectReply(chatId, text2, options3) {
@@ -240762,11 +240833,13 @@ function createTelegramAdapter(config3) {
240762
240833
  ...threadId ? { message_thread_id: Number(threadId) } : {},
240763
240834
  ...reply_parameters ? { reply_parameters } : {}
240764
240835
  });
240836
+ typing.markOutbound(chatId, threadId);
240765
240837
  },
240766
240838
  async handleTurnLifecycleEvent(event2) {
240767
240839
  if (!running)
240768
240840
  return;
240769
240841
  if (event2.type === "queued") {
240842
+ typing.start(event2.source);
240770
240843
  return;
240771
240844
  }
240772
240845
  if (event2.type === "processing") {
@@ -240806,7 +240879,7 @@ function createTelegramAdapter(config3) {
240806
240879
  ...threadId ? { message_thread_id: Number(threadId) } : {},
240807
240880
  ...reply_parameters ? { reply_parameters } : {}
240808
240881
  });
240809
- typing.clearChat(event2.source.chatId);
240882
+ typing.stop(event2.source);
240810
240883
  },
240811
240884
  onMessage: undefined
240812
240885
  };
@@ -246768,6 +246841,126 @@ var init_utils7 = __esm(() => {
246768
246841
  init_lifecycle_error();
246769
246842
  });
246770
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
+
246771
246964
  // src/channels/discord/adapter.ts
246772
246965
  import { basename as basename16 } from "node:path";
246773
246966
  function createDiscordAdapter(config3) {
@@ -246778,7 +246971,22 @@ function createDiscordAdapter(config3) {
246778
246971
  const lifecycleStateByMessageKey = new Map;
246779
246972
  const lifecycleOperationByMessageKey = new Map;
246780
246973
  const lifecycleErrorReplyKeys = new Map;
246781
- 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
+ });
246782
246990
  function pruneSeenIngressMessageKeys(now = Date.now()) {
246783
246991
  for (const [key2, expiresAt] of seenIngressMessageKeys) {
246784
246992
  if (expiresAt <= now) {
@@ -246824,24 +247032,6 @@ function createDiscordAdapter(config3) {
246824
247032
  source2.conversationId
246825
247033
  ].join(":");
246826
247034
  }
246827
- function getTypingChannelId(source2) {
246828
- if (source2.channel !== "discord")
246829
- return null;
246830
- const channelId = source2.threadId ?? source2.chatId;
246831
- return isNonEmptyString8(channelId) ? channelId : null;
246832
- }
246833
- function getTypingSourceKey(source2) {
246834
- const channelId = getTypingChannelId(source2);
246835
- if (!channelId)
246836
- return null;
246837
- return [
246838
- source2.accountId ?? "",
246839
- channelId,
246840
- source2.messageId ?? "",
246841
- source2.agentId,
246842
- source2.conversationId
246843
- ].join(":");
246844
- }
246845
247035
  function pruneLifecycleState(now = Date.now()) {
246846
247036
  for (const [key2, entry] of lifecycleStateByMessageKey) {
246847
247037
  if (entry.updatedAt + LIFECYCLE_STATE_TTL_MS <= now) {
@@ -246919,83 +247109,6 @@ function createDiscordAdapter(config3) {
246919
247109
  ...reply ?? {}
246920
247110
  });
246921
247111
  }
246922
- async function sendTypingAction(channelId) {
246923
- if (!running || !client)
246924
- return false;
246925
- try {
246926
- const channel = await client.channels.fetch(channelId);
246927
- if (!isDiscordTypingChannel(channel))
246928
- return false;
246929
- await channel.sendTyping();
246930
- return true;
246931
- } catch (error54) {
246932
- console.warn(`[Discord] Failed to send typing indicator for ${channelId}:`, error54 instanceof Error ? error54.message : error54);
246933
- return false;
246934
- }
246935
- }
246936
- async function startTypingForSource(source2) {
246937
- const channelId = getTypingChannelId(source2);
246938
- const sourceKey = getTypingSourceKey(source2);
246939
- if (!channelId || !sourceKey)
246940
- return;
246941
- const existing = typingByChannelId.get(channelId);
246942
- if (existing) {
246943
- existing.sourceKeys.add(sourceKey);
246944
- return;
246945
- }
246946
- if (!await sendTypingAction(channelId)) {
246947
- return;
246948
- }
246949
- const timer = setInterval(() => {
246950
- sendTypingAction(channelId).then((ok) => {
246951
- if (!ok) {
246952
- clearTypingForChannel(channelId);
246953
- }
246954
- });
246955
- }, DISCORD_TYPING_REFRESH_MS);
246956
- const timeout = setTimeout(() => {
246957
- clearTypingForChannel(channelId);
246958
- }, DISCORD_TYPING_MAX_MS);
246959
- if (typeof timer.unref === "function") {
246960
- timer.unref?.();
246961
- }
246962
- if (typeof timeout.unref === "function") {
246963
- timeout.unref?.();
246964
- }
246965
- typingByChannelId.set(channelId, {
246966
- sourceKeys: new Set([sourceKey]),
246967
- timer,
246968
- timeout
246969
- });
246970
- }
246971
- function stopTypingForSource(source2) {
246972
- const channelId = getTypingChannelId(source2);
246973
- const sourceKey = getTypingSourceKey(source2);
246974
- if (!channelId || !sourceKey)
246975
- return;
246976
- const entry = typingByChannelId.get(channelId);
246977
- if (!entry)
246978
- return;
246979
- entry.sourceKeys.delete(sourceKey);
246980
- if (entry.sourceKeys.size === 0) {
246981
- clearTypingForChannel(channelId);
246982
- }
246983
- }
246984
- function clearTypingForChannel(channelId) {
246985
- const entry = typingByChannelId.get(channelId);
246986
- if (!entry)
246987
- return;
246988
- clearInterval(entry.timer);
246989
- clearTimeout(entry.timeout);
246990
- typingByChannelId.delete(channelId);
246991
- }
246992
- function clearAllTyping() {
246993
- for (const entry of typingByChannelId.values()) {
246994
- clearInterval(entry.timer);
246995
- clearTimeout(entry.timeout);
246996
- }
246997
- typingByChannelId.clear();
246998
- }
246999
247112
  function scheduleLifecycleTransition(source2, nextState) {
247000
247113
  const key2 = getLifecycleMessageKey(source2);
247001
247114
  if (!key2)
@@ -247298,7 +247411,7 @@ function createDiscordAdapter(config3) {
247298
247411
  async stop() {
247299
247412
  if (!running || !client)
247300
247413
  return;
247301
- clearAllTyping();
247414
+ typing.clearAll();
247302
247415
  client.destroy();
247303
247416
  client = null;
247304
247417
  running = false;
@@ -247316,6 +247429,7 @@ function createDiscordAdapter(config3) {
247316
247429
  if (!running)
247317
247430
  return;
247318
247431
  if (event2.type === "queued") {
247432
+ await typing.start(event2.source);
247319
247433
  if (config3.acknowledgeMessageReaction) {
247320
247434
  await scheduleLifecycleTransition(event2.source, "queued");
247321
247435
  }
@@ -247323,12 +247437,12 @@ function createDiscordAdapter(config3) {
247323
247437
  }
247324
247438
  if (event2.type === "processing") {
247325
247439
  for (const source2 of event2.sources) {
247326
- await startTypingForSource(source2);
247440
+ await typing.start(source2);
247327
247441
  }
247328
247442
  return;
247329
247443
  }
247330
247444
  for (const source2 of event2.sources) {
247331
- stopTypingForSource(source2);
247445
+ typing.stop(source2);
247332
247446
  }
247333
247447
  const nextState = event2.outcome === "completed" ? "completed" : event2.outcome === "cancelled" ? "cancelled" : "error";
247334
247448
  if (config3.acknowledgeMessageReaction) {
@@ -247375,7 +247489,7 @@ function createDiscordAdapter(config3) {
247375
247489
  } else {
247376
247490
  await message.react(emoji3);
247377
247491
  }
247378
- clearTypingForChannel(targetChannelId2);
247492
+ typing.markOutbound(targetChannelId2);
247379
247493
  return { messageId: targetMessageId };
247380
247494
  }
247381
247495
  if (msg.mediaPath) {
@@ -247395,7 +247509,7 @@ function createDiscordAdapter(config3) {
247395
247509
  }
247396
247510
  ]
247397
247511
  });
247398
- clearTypingForChannel(targetChannelId2);
247512
+ typing.markOutbound(targetChannelId2);
247399
247513
  return { messageId: result.id };
247400
247514
  }
247401
247515
  const targetChannelId = msg.threadId ?? msg.chatId;
@@ -247413,7 +247527,7 @@ function createDiscordAdapter(config3) {
247413
247527
  });
247414
247528
  lastMessageId = result.id;
247415
247529
  }
247416
- clearTypingForChannel(targetChannelId);
247530
+ typing.markOutbound(targetChannelId);
247417
247531
  return { messageId: lastMessageId };
247418
247532
  },
247419
247533
  async sendDirectReply(chatId, text2, options3) {
@@ -247428,7 +247542,7 @@ function createDiscordAdapter(config3) {
247428
247542
  content: text2,
247429
247543
  ...reply ?? {}
247430
247544
  });
247431
- clearTypingForChannel(chatId);
247545
+ typing.markOutbound(chatId);
247432
247546
  },
247433
247547
  async prepareInboundMessage(msg, options3) {
247434
247548
  if (!options3?.isFirstRouteTurn || msg.channel !== "discord" || msg.chatType !== "channel" || !isNonEmptyString8(msg.threadId) || !client) {
@@ -247473,13 +247587,13 @@ function createDiscordAdapter(config3) {
247473
247587
  };
247474
247588
  return adapter;
247475
247589
  }
247476
- 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;
247477
247591
  var init_adapter4 = __esm(() => {
247478
247592
  init_media3();
247479
247593
  init_runtime4();
247594
+ init_typing_controller2();
247480
247595
  init_utils7();
247481
247596
  LIFECYCLE_STATE_TTL_MS = 6 * 60 * 60 * 1000;
247482
- DISCORD_TYPING_MAX_MS = 5 * 60 * 1000;
247483
247597
  });
247484
247598
 
247485
247599
  // src/channels/discord/message-actions.ts
@@ -249421,7 +249535,7 @@ function createWhatsAppTypingController(options3) {
249421
249535
  return { start, stop, isActive, clearChat, clearOwner, clearAll };
249422
249536
  }
249423
249537
  var DEFAULT_REFRESH_MS = 12000, DEFAULT_MAX_LIFETIME_MS;
249424
- var init_typing_controller2 = __esm(() => {
249538
+ var init_typing_controller3 = __esm(() => {
249425
249539
  DEFAULT_MAX_LIFETIME_MS = 5 * 60000;
249426
249540
  });
249427
249541
 
@@ -250130,7 +250244,7 @@ var init_adapter5 = __esm(() => {
250130
250244
  init_runtime5();
250131
250245
  init_session2();
250132
250246
  init_state();
250133
- init_typing_controller2();
250247
+ init_typing_controller3();
250134
250248
  STABLE_OPEN_RESET_MS = RECONNECT_WINDOW_MS;
250135
250249
  CLAIM_CONNECTION_STATE = { claimedConnectionState: true };
250136
250250
  });
@@ -253288,15 +253402,143 @@ var init_registry_commands = __esm(() => {
253288
253402
  init_types8();
253289
253403
  });
253290
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
+
253291
253533
  // src/channels/pending-control-requests.ts
253292
253534
  import { existsSync as existsSync38, mkdirSync as mkdirSync27, readFileSync as readFileSync28, writeFileSync as writeFileSync20 } from "node:fs";
253293
253535
  import { dirname as dirname24 } from "node:path";
253294
- function cloneEvent(event2) {
253536
+ function cloneEvent2(event2) {
253295
253537
  return structuredClone(event2);
253296
253538
  }
253297
253539
  function cloneStore(nextStore) {
253298
253540
  return {
253299
- requests: nextStore.requests.map((event2) => cloneEvent(event2))
253541
+ requests: nextStore.requests.map((event2) => cloneEvent2(event2))
253300
253542
  };
253301
253543
  }
253302
253544
  function isChannelControlRequestEvent(value) {
@@ -253325,7 +253567,7 @@ function ensureStoreLoaded() {
253325
253567
  const text2 = readFileSync28(storePath, "utf-8");
253326
253568
  const parsed = JSON.parse(text2);
253327
253569
  store2 = {
253328
- requests: Array.isArray(parsed.requests) ? parsed.requests.filter(isChannelControlRequestEvent).map(cloneEvent) : []
253570
+ requests: Array.isArray(parsed.requests) ? parsed.requests.filter(isChannelControlRequestEvent).map(cloneEvent2) : []
253329
253571
  };
253330
253572
  } catch {
253331
253573
  store2 = EMPTY_STORE();
@@ -253345,11 +253587,11 @@ function saveStore() {
253345
253587
  }
253346
253588
  function listPendingControlRequests() {
253347
253589
  ensureStoreLoaded();
253348
- return store2.requests.map((event2) => cloneEvent(event2));
253590
+ return store2.requests.map((event2) => cloneEvent2(event2));
253349
253591
  }
253350
253592
  function upsertPendingControlRequest(event2) {
253351
253593
  ensureStoreLoaded();
253352
- const nextEvent = cloneEvent(event2);
253594
+ const nextEvent = cloneEvent2(event2);
253353
253595
  const existingIndex = store2.requests.findIndex((candidate) => candidate.requestId === event2.requestId);
253354
253596
  if (existingIndex >= 0) {
253355
253597
  store2.requests[existingIndex] = nextEvent;
@@ -253357,7 +253599,7 @@ function upsertPendingControlRequest(event2) {
253357
253599
  store2.requests.push(nextEvent);
253358
253600
  }
253359
253601
  saveStore();
253360
- return cloneEvent(nextEvent);
253602
+ return cloneEvent2(nextEvent);
253361
253603
  }
253362
253604
  function removePendingControlRequest(requestId) {
253363
253605
  ensureStoreLoaded();
@@ -253376,181 +253618,102 @@ var init_pending_control_requests = __esm(() => {
253376
253618
  });
253377
253619
 
253378
253620
  // src/channels/registry-controls.ts
253379
- function getChannelApprovalScopeKey(params) {
253380
- return [
253381
- params.channel,
253382
- params.accountId ?? LEGACY_CHANNEL_ACCOUNT_ID,
253383
- params.chatId,
253384
- params.threadId ?? ""
253385
- ].join(":");
253386
- }
253387
-
253388
253621
  class ChannelControlRequests {
253389
253622
  deps;
253390
- pendingById = new Map;
253391
- requestIdByScope = new Map;
253623
+ coordinator;
253392
253624
  constructor(deps) {
253393
253625
  this.deps = deps;
253394
- 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());
253395
253664
  }
253396
253665
  has(requestId) {
253397
- return this.pendingById.has(requestId);
253666
+ return this.coordinator.has(requestId);
253398
253667
  }
253399
253668
  getAll() {
253400
- return Array.from(this.pendingById.values()).map((pending) => ({
253401
- event: structuredClone(pending.event),
253402
- deliveredThisProcess: pending.deliveredThisProcess
253403
- }));
253404
- }
253405
- primePersistedRequests() {
253406
- for (const event2 of listPendingControlRequests()) {
253407
- this.pendingById.set(event2.requestId, {
253408
- event: event2,
253409
- deliveredThisProcess: false
253410
- });
253411
- this.requestIdByScope.set(getChannelApprovalScopeKey({
253412
- channel: event2.source.channel,
253413
- accountId: event2.source.accountId,
253414
- chatId: event2.source.chatId,
253415
- threadId: event2.source.threadId
253416
- }), event2.requestId);
253417
- }
253669
+ return this.coordinator.getAll();
253418
253670
  }
253419
253671
  async handleNativeResponse(input) {
253420
- const pending = this.pendingById.get(input.requestId);
253421
- if (!pending)
253422
- return "expired";
253423
- const source2 = pending.event.source;
253424
- 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);
253425
- if (!matchesTarget || source2.senderId && source2.senderId !== input.senderId) {
253426
- return "forbidden";
253427
- }
253428
- const approvalResponseHandler = this.deps.getApprovalResponseHandler();
253429
- if (!approvalResponseHandler)
253430
- return "unavailable";
253431
- const handled = await approvalResponseHandler({
253432
- runtime: {
253433
- agent_id: source2.agentId,
253434
- conversation_id: source2.conversationId
253435
- },
253436
- response: input.response
253437
- });
253438
- this.clear(input.requestId);
253439
- return handled ? "handled" : "expired";
253672
+ return this.coordinator.handleNativeResponse(input);
253440
253673
  }
253441
- async deliver(requestId) {
253442
- const pending = this.pendingById.get(requestId);
253443
- if (!pending)
253444
- return false;
253445
- const event2 = pending.event;
253446
- const adapter = this.deps.getAdapter(event2.source.channel, event2.source.accountId ?? LEGACY_CHANNEL_ACCOUNT_ID);
253447
- if (!adapter)
253448
- return false;
253674
+ async register(event2) {
253449
253675
  try {
253450
- if (adapter.handleControlRequestEvent) {
253451
- await adapter.handleControlRequestEvent(event2);
253452
- } else {
253453
- await adapter.sendDirectReply(event2.source.chatId, formatChannelControlRequestPrompt(event2), { replyToMessageId: event2.source.threadId ?? event2.source.messageId });
253454
- }
253455
- pending.deliveredThisProcess = true;
253456
- return true;
253676
+ await this.coordinator.register(event2);
253457
253677
  } catch (error54) {
253458
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);
253459
- return false;
253460
253679
  }
253461
253680
  }
253462
- async register(event2) {
253463
- const scopeKey = getChannelApprovalScopeKey({
253464
- channel: event2.source.channel,
253465
- accountId: event2.source.accountId,
253466
- chatId: event2.source.chatId,
253467
- threadId: event2.source.threadId
253468
- });
253469
- const existingRequestId = this.requestIdByScope.get(scopeKey);
253470
- if (existingRequestId)
253471
- this.clear(existingRequestId);
253472
- this.pendingById.set(event2.requestId, {
253473
- event: event2,
253474
- deliveredThisProcess: false
253475
- });
253476
- this.requestIdByScope.set(scopeKey, event2.requestId);
253477
- upsertPendingControlRequest(event2);
253478
- await this.deliver(event2.requestId);
253479
- }
253480
253681
  async redeliver(requestId) {
253481
- 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
+ }
253482
253689
  }
253483
253690
  clear(requestId) {
253484
- removePendingControlRequest(requestId);
253485
- const pending = this.pendingById.get(requestId);
253486
- if (!pending)
253487
- return;
253488
- this.pendingById.delete(requestId);
253489
- const scopeKey = getChannelApprovalScopeKey({
253490
- channel: pending.event.source.channel,
253491
- accountId: pending.event.source.accountId,
253492
- chatId: pending.event.source.chatId,
253493
- threadId: pending.event.source.threadId
253494
- });
253495
- if (this.requestIdByScope.get(scopeKey) === requestId) {
253496
- this.requestIdByScope.delete(scopeKey);
253497
- }
253691
+ this.coordinator.clear(requestId);
253498
253692
  }
253499
253693
  clearAll() {
253500
- this.pendingById.clear();
253501
- this.requestIdByScope.clear();
253694
+ this.coordinator.clearAll();
253502
253695
  }
253503
- async tryHandleInbound(adapter, msg) {
253696
+ async tryHandleInbound(_adapter, msg) {
253504
253697
  const channelCommand = parseChannelSlashCommand(msg.text) ?? (msg.channel === "slack" && msg.isMention === true ? parseChannelBangCommand(msg.text) : null);
253505
- if (channelCommand)
253506
- return false;
253507
- const scopeKey = getChannelApprovalScopeKey({
253698
+ return this.coordinator.tryHandleInbound({
253508
253699
  channel: msg.channel,
253509
253700
  accountId: msg.accountId,
253510
253701
  chatId: msg.chatId,
253511
- threadId: msg.threadId
253512
- });
253513
- const requestId = this.requestIdByScope.get(scopeKey);
253514
- if (!requestId)
253515
- return false;
253516
- const pending = this.pendingById.get(requestId);
253517
- if (!pending) {
253518
- this.requestIdByScope.delete(scopeKey);
253519
- return false;
253520
- }
253521
- if (pending.event.source.senderId && pending.event.source.senderId !== msg.senderId) {
253522
- return false;
253523
- }
253524
- if (msg.channel === "slack" && pending.event.kind === "generic_tool_approval") {
253525
- return false;
253526
- }
253527
- const parsed = parseChannelControlRequestResponse(pending.event, msg.text);
253528
- if (parsed.type === "reprompt") {
253529
- await adapter.sendDirectReply(msg.chatId, parsed.message, buildDirectReplyOptions(msg));
253530
- return true;
253531
- }
253532
- const approvalResponseHandler = this.deps.getApprovalResponseHandler();
253533
- if (!approvalResponseHandler) {
253534
- 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));
253535
- return true;
253536
- }
253537
- const handled = await approvalResponseHandler({
253538
- runtime: {
253539
- agent_id: pending.event.source.agentId,
253540
- conversation_id: pending.event.source.conversationId
253541
- },
253542
- response: parsed.response
253702
+ messageId: msg.messageId,
253703
+ threadId: msg.threadId,
253704
+ senderId: msg.senderId,
253705
+ text: msg.text,
253706
+ bypass: Boolean(channelCommand)
253543
253707
  });
253544
- this.clear(requestId);
253545
- if (!handled) {
253546
- await adapter.sendDirectReply(msg.chatId, "That approval prompt expired before I could use your reply. Please ask the agent to try again.", buildDirectReplyOptions(msg));
253547
- }
253548
- return true;
253708
+ }
253709
+ getAdapter(event2) {
253710
+ return this.deps.getAdapter(event2.source.channel, event2.source.accountId ?? LEGACY_CHANNEL_ACCOUNT_ID);
253549
253711
  }
253550
253712
  }
253551
253713
  var init_registry_controls = __esm(() => {
253552
253714
  init_accounts();
253553
253715
  init_commands();
253716
+ init_control_request_coordinator();
253554
253717
  init_pending_control_requests();
253555
253718
  init_registry_presentation();
253556
253719
  });
@@ -266785,7 +266948,7 @@ function shouldProcessInboundMessageDirectly(runtime, parsed) {
266785
266948
  });
266786
266949
  return getListenerBlockedReason(runtime.turnLifecycle.snapshot(), activeScope ? getPendingControlRequestCount(runtime.listener, activeScope) : 0) === null;
266787
266950
  }
266788
- function consumeQueuedTurn(runtime, options3) {
266951
+ function consumeQueuedTurn(runtime) {
266789
266952
  const queuedItems = runtime.queueRuntime.peek();
266790
266953
  const firstQueuedItem = queuedItems[0];
266791
266954
  if (!firstQueuedItem || !isCoalescable(firstQueuedItem.kind)) {
@@ -266835,18 +266998,6 @@ function consumeQueuedTurn(runtime, options3) {
266835
266998
  if (!hasMessage && !hasTaskNotification && !hasCronPrompt && !hasModContinue || queueLen === 0) {
266836
266999
  return null;
266837
267000
  }
266838
- if (options3?.matchActiveSuperRun) {
266839
- const activeSuperRunId = runtime.superRunId;
266840
- const crossesSuperRun = queuedItems.slice(0, queueLen).some((item) => {
266841
- if (item.kind !== "message")
266842
- return false;
266843
- const queuedSuperRunId = runtime.queuedMessagesByItemId.get(item.id)?.superRunId ?? null;
266844
- return queuedSuperRunId !== activeSuperRunId;
266845
- });
266846
- if (crossesSuperRun) {
266847
- return null;
266848
- }
266849
- }
266850
267001
  const dequeuedBatch = runtime.queueRuntime.consumeItems(queueLen);
266851
267002
  if (!dequeuedBatch) {
266852
267003
  return null;
@@ -266934,7 +267085,60 @@ var init_queue = __esm(async () => {
266934
267085
  await init_image_policy();
266935
267086
  });
266936
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
+
266937
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
+ }
266938
267142
  function ensureConversationQueueRuntime(listener, runtime) {
266939
267143
  if (runtime.queueRuntime) {
266940
267144
  return runtime;
@@ -266947,7 +267151,7 @@ function ensureConversationQueueRuntime(listener, runtime) {
266947
267151
  },
266948
267152
  onDequeued: (batch) => {
266949
267153
  runtime.pendingTurns = batch.queueLenAfter;
266950
- scheduleQueueEmit(listener, getQueueItemsScope(batch.items));
267154
+ scheduleQueueEmit(listener, getQueueItemsScope(batch.items), batch.items.map((item) => queueRemovalTransition(item, "dequeued")));
266951
267155
  },
266952
267156
  onBlocked: () => {
266953
267157
  scheduleQueueEmit(listener, {
@@ -266957,13 +267161,23 @@ function ensureConversationQueueRuntime(listener, runtime) {
266957
267161
  },
266958
267162
  onCleared: (_reason, _clearedCount, items3) => {
266959
267163
  runtime.pendingTurns = 0;
266960
- scheduleQueueEmit(listener, getQueueItemsScope(items3));
267164
+ scheduleQueueEmit(listener, getQueueItemsScope(items3), items3.map((item) => queueRemovalTransition(item, "cancelled")));
266961
267165
  evictConversationRuntimeIfIdle(runtime);
266962
267166
  },
266963
267167
  onDropped: (item, _reason, queueLen) => {
266964
267168
  runtime.pendingTurns = queueLen;
266965
267169
  runtime.queuedMessagesByItemId.delete(item.id);
266966
- 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
+ ]);
266967
267181
  evictConversationRuntimeIfIdle(runtime);
266968
267182
  }
266969
267183
  }
@@ -266975,7 +267189,7 @@ function getOrCreateScopedRuntime(listener, agentId, conversationId) {
266975
267189
  }
266976
267190
  var init_conversation_runtime = __esm(async () => {
266977
267191
  init_queue_runtime();
266978
- init_protocol_outbound();
267192
+ init_queue_update_outbound();
266979
267193
  init_runtime();
266980
267194
  await init_queue();
266981
267195
  });
@@ -267581,8 +267795,9 @@ async function sendEnvironmentMessage(connectionId, body3) {
267581
267795
  async function getEnvironmentConnection(deviceId) {
267582
267796
  return apiRequest("GET", `/v1/environments/${encodeURIComponent(deviceId)}`);
267583
267797
  }
267584
- async function createAgentSandbox(agentId) {
267585
- 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 } : {});
267586
267801
  }
267587
267802
  function isEnvironmentOnline(environment2) {
267588
267803
  return typeof environment2.connectionId === "string" && environment2.connectionId.length > 0 && typeof environment2.lastHeartbeat === "number" && Date.now() - environment2.lastHeartbeat < 120000;
@@ -267622,7 +267837,9 @@ async function resolveEnvironmentConnectionId(selector) {
267622
267837
  async function resolveAgentSandboxConnectionId(agentId, options3 = {}) {
267623
267838
  const timeoutMs = options3.timeoutMs ?? 3 * 60000;
267624
267839
  const pollIntervalMs = options3.pollIntervalMs ?? 2000;
267625
- const sandbox = await createAgentSandbox(agentId);
267840
+ const sandbox = await createAgentSandbox(agentId, {
267841
+ conversationId: options3.conversationId
267842
+ });
267626
267843
  const deviceId = sandbox.deviceId || `sandbox-${agentId}`;
267627
267844
  const deadline = Date.now() + timeoutMs;
267628
267845
  let lastEnvironment = null;
@@ -273239,6 +273456,99 @@ var init_memory_subagent_completion = __esm(() => {
273239
273456
  init_system_prompt_warning();
273240
273457
  });
273241
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
+
273242
273552
  // src/cli/helpers/reflection-integration.ts
273243
273553
  function buildReflectionIntegrationConversationTitle(reflectionSubagentId) {
273244
273554
  return reflectionSubagentId ? `Reflection integration (reflection ${reflectionSubagentId})` : "Reflection integration";
@@ -273803,7 +274113,7 @@ async function launchReflectionSubagent(options3) {
273803
274113
  recompileQueuedByConversation,
273804
274114
  logRecompileFailure: (message) => debugWarn("memory", message)
273805
274115
  });
273806
- await finalizeAutoReflectionPayload(agentId, conversationId, autoPayload.payloadPath, autoPayload.endSnapshotLine, completionSuccess);
274116
+ await finalizeAutoReflectionCompletion(agentId, conversationId, autoPayload.payloadPath, autoPayload.endSnapshotLine, autoPayload.endMessageId, completionSuccess);
273807
274117
  await onCompletionMessage?.(completionMessage, {
273808
274118
  success: completionSuccess,
273809
274119
  error: error54,
@@ -273852,6 +274162,7 @@ var init_reflection_launcher = __esm(() => {
273852
274162
  init_backend2();
273853
274163
  init_memory_reminder();
273854
274164
  init_memory_subagent_completion();
274165
+ init_reflection_completion();
273855
274166
  init_reflection_transcript();
273856
274167
  init_telemetry();
273857
274168
  init_reflection_threshold_feedback();
@@ -276356,7 +276667,7 @@ var init_identity2 = __esm(() => {
276356
276667
  function getListenerOAuthDeps() {
276357
276668
  return listenerOAuthDepsOverride ?? defaultListenerOAuthDeps;
276358
276669
  }
276359
- function errorMessage(error54) {
276670
+ function errorMessage2(error54) {
276360
276671
  return error54 instanceof Error ? error54.message : String(error54);
276361
276672
  }
276362
276673
  function getListenerServerUrl(settings3) {
@@ -276439,7 +276750,7 @@ async function resolveListenerAuth(deviceId, connectionName, options3) {
276439
276750
  } catch (refreshError) {
276440
276751
  const retryable = !(refreshError instanceof OAuthRefreshError) || refreshError.retryable;
276441
276752
  if (retryable && isAccessTokenStillValid(settings3, apiKey)) {
276442
- 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)}`);
276443
276754
  return { serverUrl, apiKey };
276444
276755
  }
276445
276756
  if (retryable) {
@@ -276448,7 +276759,7 @@ async function resolveListenerAuth(deviceId, connectionName, options3) {
276448
276759
  if (!allowInteractiveOAuth) {
276449
276760
  throw new ListenerReauthenticationRequiredError(refreshError);
276450
276761
  }
276451
- console.warn(`Token refresh failed: ${errorMessage(refreshError)}`);
276762
+ console.warn(`Token refresh failed: ${errorMessage2(refreshError)}`);
276452
276763
  apiKey = undefined;
276453
276764
  }
276454
276765
  }
@@ -276503,13 +276814,13 @@ var init_auth = __esm(() => {
276503
276814
  };
276504
276815
  ListenerAuthRetryableError = class ListenerAuthRetryableError extends Error {
276505
276816
  constructor(refreshError) {
276506
- super(`Could not refresh listener credentials: ${errorMessage(refreshError)}`);
276817
+ super(`Could not refresh listener credentials: ${errorMessage2(refreshError)}`);
276507
276818
  this.name = "ListenerAuthRetryableError";
276508
276819
  }
276509
276820
  };
276510
276821
  ListenerReauthenticationRequiredError = class ListenerReauthenticationRequiredError extends Error {
276511
276822
  constructor(refreshError) {
276512
- const detail = refreshError ? `: ${errorMessage(refreshError)}` : "";
276823
+ const detail = refreshError ? `: ${errorMessage2(refreshError)}` : "";
276513
276824
  super(`Saved Letta API credentials require reauthentication${detail}. Run letta to sign in again, or set LETTA_API_KEY.`);
276514
276825
  this.name = "ListenerReauthenticationRequiredError";
276515
276826
  }
@@ -276886,11 +277197,11 @@ function resolvePendingApprovalResolver(runtime, response, connectionId) {
276886
277197
  setCommandLoopStatus(runtime, "WAITING_ON_INPUT");
276887
277198
  }
276888
277199
  pending.resolve(response);
276889
- emitLoopStatusIfOpen(runtime, {
277200
+ emitLoopStatusIfOpen(runtime.listener, {
276890
277201
  agent_id: runtime.agentId,
276891
277202
  conversation_id: runtime.conversationId
276892
277203
  });
276893
- emitDeviceStatusIfOpen(runtime, {
277204
+ emitDeviceStatusIfOpen(runtime.listener, {
276894
277205
  agent_id: runtime.agentId,
276895
277206
  conversation_id: runtime.conversationId
276896
277207
  });
@@ -276905,11 +277216,11 @@ function rejectPendingApprovalResolvers(runtime, reason) {
276905
277216
  if (!runtime.isProcessing && !runtime.cancelRequested) {
276906
277217
  setCommandLoopStatus(runtime, "WAITING_ON_INPUT");
276907
277218
  }
276908
- emitLoopStatusIfOpen(runtime, {
277219
+ emitLoopStatusIfOpen(runtime.listener, {
276909
277220
  agent_id: runtime.agentId,
276910
277221
  conversation_id: runtime.conversationId
276911
277222
  });
276912
- emitDeviceStatusIfOpen(runtime, {
277223
+ emitDeviceStatusIfOpen(runtime.listener, {
276913
277224
  agent_id: runtime.agentId,
276914
277225
  conversation_id: runtime.conversationId
276915
277226
  });
@@ -277014,11 +277325,11 @@ function requestApprovalOverWS(runtime, socket, turnLease, requestId, controlReq
277014
277325
  runtime.turnLifecycle.recordStopReason(turnLease, "requires_approval");
277015
277326
  setTurnLoopStatus(runtime, turnLease, "WAITING_ON_APPROVAL");
277016
277327
  emitProtocolV2Message(socket, runtime, controlRequest, scope, TO_SUBSCRIBERS);
277017
- emitLoopStatusIfOpen(runtime, {
277328
+ emitLoopStatusIfOpen(runtime.listener, {
277018
277329
  agent_id: runtime.agentId,
277019
277330
  conversation_id: runtime.conversationId
277020
277331
  });
277021
- emitDeviceStatusIfOpen(runtime, {
277332
+ emitDeviceStatusIfOpen(runtime.listener, {
277022
277333
  agent_id: runtime.agentId,
277023
277334
  conversation_id: runtime.conversationId
277024
277335
  });
@@ -329159,8 +329470,8 @@ ${lanes.join(`
329159
329470
  }
329160
329471
  function resolveExternalModuleName(location, moduleReferenceExpression, ignoreErrors) {
329161
329472
  const isClassic = getEmitModuleResolutionKind(compilerOptions) === 1;
329162
- 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;
329163
- 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);
329164
329475
  }
329165
329476
  function resolveExternalModuleNameWorker(location, moduleReferenceExpression, moduleNotFoundError, ignoreErrors = false, isForAugmentation = false) {
329166
329477
  return isStringLiteralLike(moduleReferenceExpression) ? resolveExternalModule(location, moduleReferenceExpression.text, moduleNotFoundError, !ignoreErrors ? moduleReferenceExpression : undefined, isForAugmentation) : undefined;
@@ -340186,8 +340497,8 @@ ${lanes.join(`
340186
340497
  if (moduleSymbol.flags & targetMeaning) {
340187
340498
  links.resolvedType = resolveImportSymbolType(node, links, moduleSymbol, targetMeaning);
340188
340499
  } else {
340189
- 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;
340190
- 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);
340191
340502
  links.resolvedSymbol = unknownSymbol;
340192
340503
  links.resolvedType = errorType;
340193
340504
  }
@@ -341284,7 +341595,7 @@ ${lanes.join(`
341284
341595
  function elaborateElementwise(iterator2, source2, target2, relation, containingMessageChain, errorOutputContainer) {
341285
341596
  let reportedError = false;
341286
341597
  for (const value of iterator2) {
341287
- const { errorNode: prop, innerExpression: next, nameType, errorMessage: errorMessage2 } = value;
341598
+ const { errorNode: prop, innerExpression: next, nameType, errorMessage: errorMessage3 } = value;
341288
341599
  let targetPropType = getBestMatchIndexedAccessTypeOrUndefined(source2, target2, nameType);
341289
341600
  if (!targetPropType || targetPropType.flags & 8388608)
341290
341601
  continue;
@@ -341307,9 +341618,9 @@ ${lanes.join(`
341307
341618
  const sourceIsOptional = !!(propName && (getPropertyOfType(source2, propName) || unknownSymbol).flags & 16777216);
341308
341619
  targetPropType = removeMissingType(targetPropType, targetIsOptional);
341309
341620
  sourcePropType = removeMissingType(sourcePropType, targetIsOptional && sourceIsOptional);
341310
- const result = checkTypeRelatedTo(specificSource, targetPropType, relation, prop, errorMessage2, containingMessageChain, resultObj);
341621
+ const result = checkTypeRelatedTo(specificSource, targetPropType, relation, prop, errorMessage3, containingMessageChain, resultObj);
341311
341622
  if (result && specificSource !== sourcePropType) {
341312
- checkTypeRelatedTo(sourcePropType, targetPropType, relation, prop, errorMessage2, containingMessageChain, resultObj);
341623
+ checkTypeRelatedTo(sourcePropType, targetPropType, relation, prop, errorMessage3, containingMessageChain, resultObj);
341313
341624
  }
341314
341625
  }
341315
341626
  if (resultObj.errors) {
@@ -341342,7 +341653,7 @@ ${lanes.join(`
341342
341653
  const iterationType = nonTupleOrArrayLikeTargetParts !== neverType2 ? getIterationTypeOfIterable(13, 0, nonTupleOrArrayLikeTargetParts, undefined) : undefined;
341343
341654
  let reportedError = false;
341344
341655
  for (let status = iterator2.next();!status.done; status = iterator2.next()) {
341345
- const { errorNode: prop, innerExpression: next, nameType, errorMessage: errorMessage2 } = status.value;
341656
+ const { errorNode: prop, innerExpression: next, nameType, errorMessage: errorMessage3 } = status.value;
341346
341657
  let targetPropType = iterationType;
341347
341658
  const targetIndexedPropType = tupleOrArrayLikeTargetParts !== neverType2 ? getBestMatchIndexedAccessTypeOrUndefined(source2, tupleOrArrayLikeTargetParts, nameType) : undefined;
341348
341659
  if (targetIndexedPropType && !(targetIndexedPropType.flags & 8388608)) {
@@ -341369,9 +341680,9 @@ ${lanes.join(`
341369
341680
  const sourceIsOptional = !!(propName && (getPropertyOfType(source2, propName) || unknownSymbol).flags & 16777216);
341370
341681
  targetPropType = removeMissingType(targetPropType, targetIsOptional);
341371
341682
  sourcePropType = removeMissingType(sourcePropType, targetIsOptional && sourceIsOptional);
341372
- const result = checkTypeRelatedTo(specificSource, targetPropType, relation, prop, errorMessage2, containingMessageChain, resultObj);
341683
+ const result = checkTypeRelatedTo(specificSource, targetPropType, relation, prop, errorMessage3, containingMessageChain, resultObj);
341373
341684
  if (result && specificSource !== sourcePropType) {
341374
- checkTypeRelatedTo(sourcePropType, targetPropType, relation, prop, errorMessage2, containingMessageChain, resultObj);
341685
+ checkTypeRelatedTo(sourcePropType, targetPropType, relation, prop, errorMessage3, containingMessageChain, resultObj);
341375
341686
  }
341376
341687
  }
341377
341688
  }
@@ -350235,9 +350546,9 @@ ${lanes.join(`
350235
350546
  return;
350236
350547
  }
350237
350548
  const isClassic = getEmitModuleResolutionKind(compilerOptions) === 1;
350238
- 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;
350239
350550
  const specifier = getJSXRuntimeImportSpecifier(file3, runtimeImportSpecifier);
350240
- const mod = resolveExternalModule(specifier || location, runtimeImportSpecifier, errorMessage2, location);
350551
+ const mod = resolveExternalModule(specifier || location, runtimeImportSpecifier, errorMessage3, location);
350241
350552
  const result = mod && mod !== unknownSymbol ? getMergedSymbol(resolveSymbol(mod)) : undefined;
350242
350553
  if (links) {
350243
350554
  links.jsxImplicitImportContainer = result || false;
@@ -359559,7 +359870,7 @@ ${lanes.join(`
359559
359870
  if (baseDeclarationFlags & 2 || derivedDeclarationFlags & 2) {
359560
359871
  continue;
359561
359872
  }
359562
- let errorMessage2;
359873
+ let errorMessage3;
359563
359874
  const basePropertyFlags = base3.flags & 98308;
359564
359875
  const derivedPropertyFlags = derived.flags & 98308;
359565
359876
  if (basePropertyFlags && derivedPropertyFlags) {
@@ -359588,14 +359899,14 @@ ${lanes.join(`
359588
359899
  continue;
359589
359900
  } else {
359590
359901
  Debug.assert(!!(derived.flags & 98304));
359591
- 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;
359592
359903
  }
359593
359904
  } else if (base3.flags & 98304) {
359594
- 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;
359595
359906
  } else {
359596
- 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;
359597
359908
  }
359598
- 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));
359599
359910
  }
359600
359911
  }
359601
359912
  for (const [errorNode, memberInfo] of notImplementedInfo) {
@@ -360441,10 +360752,10 @@ ${lanes.join(`
360441
360752
  }
360442
360753
  return false;
360443
360754
  }
360444
- function checkGrammarModuleElementContext(node, errorMessage2) {
360755
+ function checkGrammarModuleElementContext(node, errorMessage3) {
360445
360756
  const isInAppropriateContext = node.parent.kind === 308 || node.parent.kind === 269 || node.parent.kind === 268;
360446
360757
  if (!isInAppropriateContext) {
360447
- grammarErrorOnFirstToken(node, errorMessage2);
360758
+ grammarErrorOnFirstToken(node, errorMessage3);
360448
360759
  }
360449
360760
  return !isInAppropriateContext;
360450
360761
  }
@@ -387004,14 +387315,14 @@ ${lanes.join(`
387004
387315
  return output;
387005
387316
  }
387006
387317
  function formatDiagnostic2(diagnostic, host) {
387007
- 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()}`;
387008
387319
  if (diagnostic.file) {
387009
387320
  const { line, character } = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
387010
387321
  const fileName = diagnostic.file.fileName;
387011
387322
  const relativeFileName = convertToRelativePath(fileName, host.getCurrentDirectory(), (fileName2) => host.getCanonicalFileName(fileName2));
387012
- return `${relativeFileName}(${line + 1},${character + 1}): ` + errorMessage2;
387323
+ return `${relativeFileName}(${line + 1},${character + 1}): ` + errorMessage3;
387013
387324
  }
387014
- return errorMessage2;
387325
+ return errorMessage3;
387015
387326
  }
387016
387327
  var ForegroundColorEscapeSequences = /* @__PURE__ */ ((ForegroundColorEscapeSequences2) => {
387017
387328
  ForegroundColorEscapeSequences2["Grey"] = "\x1B[90m";
@@ -455089,9 +455400,9 @@ async function drainStream(stream12, buffers, refresh, abortSignal, onFirstMessa
455089
455400
  }
455090
455401
  }
455091
455402
  } catch (e2) {
455092
- const errorMessage2 = e2 instanceof Error ? e2.message : String(e2);
455403
+ const errorMessage3 = e2 instanceof Error ? e2.message : String(e2);
455093
455404
  const sdkDiagnostic = consumeLastSDKDiagnostic();
455094
- const errorMessageWithDiagnostic = sdkDiagnostic ? `${errorMessage2} [${sdkDiagnostic}]` : errorMessage2;
455405
+ const errorMessageWithDiagnostic = sdkDiagnostic ? `${errorMessage3} [${sdkDiagnostic}]` : errorMessage3;
455095
455406
  debugWarn("drainStream", "Stream error caught: %s last_chunk=%s stream=%s", errorMessageWithDiagnostic, lastChunkDebugSummary, summarizeStreamForDebug(stream12));
455096
455407
  if (e2 instanceof Error && e2.stack) {
455097
455408
  debugWarn("drainStream", "Stream error stack: %s", e2.stack);
@@ -456012,8 +456323,7 @@ async function resolveRecoveredApprovalResponse(runtime, socket, response, proce
456012
456323
  const workingDirectory = getConversationWorkingDirectory(runtime.listener, recovered.agentId, recovered.conversationId);
456013
456324
  const scope = {
456014
456325
  agent_id: recovered.agentId,
456015
- conversation_id: recovered.conversationId,
456016
- ...opts?.superRunId ? { super_run_id: opts.superRunId } : {}
456326
+ conversation_id: recovered.conversationId
456017
456327
  };
456018
456328
  const respondedEntry = recovered.approvalsByRequestId.get(requestId);
456019
456329
  let autoDecisionsToAppend = [];
@@ -456066,8 +456376,7 @@ async function resolveRecoveredApprovalResponse(runtime, socket, response, proce
456066
456376
  const recoveryLease = pendingRequestIdsAfterResponse.length === 0 ? runtime.turnLifecycle.begin({
456067
456377
  origin: "approval_recovery",
456068
456378
  workingDirectory,
456069
- initialStatus: "EXECUTING_CLIENT_SIDE_TOOL",
456070
- superRunId: opts?.superRunId
456379
+ initialStatus: "EXECUTING_CLIENT_SIDE_TOOL"
456071
456380
  }) : null;
456072
456381
  let continuationFinalized = false;
456073
456382
  try {
@@ -456221,9 +456530,7 @@ async function resolveRecoveredApprovalResponse(runtime, socket, response, proce
456221
456530
  }
456222
456531
  ]);
456223
456532
  let continuationBatchId = `batch-recovered-${crypto.randomUUID()}`;
456224
- const consumedQueuedTurn = consumeQueuedTurn(runtime, {
456225
- matchActiveSuperRun: true
456226
- });
456533
+ const consumedQueuedTurn = consumeQueuedTurn(runtime);
456227
456534
  if (consumedQueuedTurn) {
456228
456535
  const { dequeuedBatch, queuedTurn } = consumedQueuedTurn;
456229
456536
  continuationBatchId = dequeuedBatch.batchId;
@@ -456237,7 +456544,6 @@ async function resolveRecoveredApprovalResponse(runtime, socket, response, proce
456237
456544
  type: "message",
456238
456545
  agentId: recovered.agentId,
456239
456546
  conversationId: recovered.conversationId,
456240
- ...opts?.superRunId ? { superRunId: opts.superRunId } : {},
456241
456547
  messages: continuationInput.messages
456242
456548
  }, socket, runtime, opts?.onStatusChange, opts?.connectionId, continuationBatchId, recoveryLease);
456243
456549
  if (runtime.turnLifecycle.isCurrent(recoveryLease)) {
@@ -456263,21 +456569,17 @@ async function resolveRecoveredApprovalResponse(runtime, socket, response, proce
456263
456569
  recovered.responsesByRequestId.clear();
456264
456570
  }
456265
456571
  const stopReason = recoveryLease.signal.aborted ? "cancelled" : "error";
456266
- try {
456267
- finishListenerTurn(runtime, recoveryLease, {
456268
- stopReason,
456269
- socket,
456270
- agentId: recovered.agentId,
456271
- conversationId: recovered.conversationId,
456272
- turnId: `batch-recovered-${requestId}`,
456273
- error: stopReason === "error" ? getTranscriptLoopErrorMessage({
456274
- error: error54,
456275
- message: error54 instanceof Error ? error54.message : String(error54)
456276
- }) : undefined
456277
- });
456278
- } finally {
456279
- runtime.turnLifecycle.releaseSuperRunId(recoveryLease);
456280
- }
456572
+ finishListenerTurn(runtime, recoveryLease, {
456573
+ stopReason,
456574
+ socket,
456575
+ agentId: recovered.agentId,
456576
+ conversationId: recovered.conversationId,
456577
+ turnId: `batch-recovered-${requestId}`,
456578
+ error: stopReason === "error" ? getTranscriptLoopErrorMessage({
456579
+ error: error54,
456580
+ message: error54 instanceof Error ? error54.message : String(error54)
456581
+ }) : undefined
456582
+ });
456281
456583
  throw error54;
456282
456584
  }
456283
456585
  }
@@ -456624,9 +456926,7 @@ async function resolveStaleApprovals(runtime, socket, turnLease, deps = {}) {
456624
456926
  otid: crypto.randomUUID()
456625
456927
  }
456626
456928
  ]);
456627
- const consumedQueuedTurn = consumeQueuedTurn(runtime, {
456628
- matchActiveSuperRun: true
456629
- });
456929
+ const consumedQueuedTurn = consumeQueuedTurn(runtime);
456630
456930
  if (consumedQueuedTurn) {
456631
456931
  const { dequeuedBatch, queuedTurn } = consumedQueuedTurn;
456632
456932
  continuationInput = appendQueuedTurnToInput(continuationInput, queuedTurn);
@@ -459399,9 +459699,7 @@ async function handleApprovalStop(params) {
459399
459699
  }
459400
459700
  ]);
459401
459701
  let continuationBatchId = dequeuedBatchId;
459402
- const consumedQueuedTurn = consumeQueuedTurn(runtime, {
459403
- matchActiveSuperRun: true
459404
- });
459702
+ const consumedQueuedTurn = consumeQueuedTurn(runtime);
459405
459703
  if (consumedQueuedTurn) {
459406
459704
  const { dequeuedBatch, queuedTurn } = consumedQueuedTurn;
459407
459705
  continuationBatchId = dequeuedBatch.batchId;
@@ -461016,8 +461314,7 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
461016
461314
  let lastNeedsUserInputToolCallIds = [];
461017
461315
  const turnLease = existingTurnLease ?? runtime.turnLifecycle.begin({
461018
461316
  origin: "message",
461019
- workingDirectory: turnWorkingDirectory,
461020
- superRunId: msg.superRunId
461317
+ workingDirectory: turnWorkingDirectory
461021
461318
  });
461022
461319
  if (connectionId) {
461023
461320
  runtime.activeConnectionId = connectionId;
@@ -461136,7 +461433,6 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
461136
461433
  } : {},
461137
461434
  ...providerFallback.overrideModel ? { overrideModel: providerFallback.overrideModel } : {},
461138
461435
  ...msg.actingUserId ? { actingUserId: msg.actingUserId } : {},
461139
- ...msg.superRunId ? { superRunId: msg.superRunId } : {},
461140
461436
  ...pendingNormalizationInterruptedToolCallIds.length > 0 ? {
461141
461437
  approvalNormalization: {
461142
461438
  interruptedToolCallIds: pendingNormalizationInterruptedToolCallIds
@@ -461449,10 +461745,10 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
461449
461745
  });
461450
461746
  break;
461451
461747
  }
461452
- const errorMessage2 = errorDetail2 || `Unexpected stop reason: ${stopReason}`;
461748
+ const errorMessage3 = errorDetail2 || `Unexpected stop reason: ${stopReason}`;
461453
461749
  const terminalRunId = runId || runtime.activeRunId || runErrorInfo2?.run_id;
461454
461750
  const noticeParams = {
461455
- message: errorMessage2,
461751
+ message: errorMessage3,
461456
461752
  agentId,
461457
461753
  conversationId,
461458
461754
  runErrorInfo: runErrorInfo2 ?? undefined,
@@ -461475,7 +461771,7 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
461475
461771
  isTerminal: true,
461476
461772
  runId: terminalRunId
461477
461773
  });
461478
- runtime.lastTerminalLoopErrorMessage = formattedError ?? errorMessage2;
461774
+ runtime.lastTerminalLoopErrorMessage = formattedError ?? errorMessage3;
461479
461775
  runtime.lastTerminalLoopErrorRunId = terminalRunId ?? null;
461480
461776
  break;
461481
461777
  }
@@ -461600,10 +461896,10 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
461600
461896
  });
461601
461897
  return;
461602
461898
  }
461603
- const errorMessage2 = error54 instanceof Error ? error54.message : String(error54);
461899
+ const errorMessage3 = error54 instanceof Error ? error54.message : String(error54);
461604
461900
  const terminalRunId = runtime.activeRunId;
461605
461901
  const noticeParams = {
461606
- message: errorMessage2,
461902
+ message: errorMessage3,
461607
461903
  agentId,
461608
461904
  conversationId,
461609
461905
  error: error54,
@@ -461626,7 +461922,7 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
461626
461922
  isTerminal: true,
461627
461923
  runId: terminalRunId
461628
461924
  });
461629
- runtime.lastTerminalLoopErrorMessage = formattedError ?? errorMessage2;
461925
+ runtime.lastTerminalLoopErrorMessage = formattedError ?? errorMessage3;
461630
461926
  runtime.lastTerminalLoopErrorRunId = terminalRunId ?? null;
461631
461927
  if (isDebugEnabled()) {
461632
461928
  console.error("[Listen] Error handling message:", error54);
@@ -461662,7 +461958,6 @@ async function handleIncomingMessageInner(msg, socket, runtime, onStatusChange,
461662
461958
  }
461663
461959
  } finally {
461664
461960
  releaseListenerTurnContext({ runtime, agentId, conversationId });
461665
- runtime.turnLifecycle.releaseSuperRunId(turnLease);
461666
461961
  }
461667
461962
  evictConversationRuntimeIfIdle(runtime);
461668
461963
  }
@@ -461789,8 +462084,7 @@ async function handleApprovalResponseInput(listener, params, deps = {
461789
462084
  }
461790
462085
  if (await deps.resolveRecoveredApprovalResponse(targetRuntime, params.socket, params.response, handleIncomingMessage, {
461791
462086
  onStatusChange: params.opts.onStatusChange,
461792
- connectionId: params.opts.connectionId,
461793
- ...params.runtime.super_run_id ? { superRunId: params.runtime.super_run_id } : {}
462087
+ connectionId: params.opts.connectionId
461794
462088
  })) {
461795
462089
  deps.scheduleQueuePump(targetRuntime, params.socket, params.opts, params.processQueuedTurn);
461796
462090
  return true;
@@ -464248,16 +464542,16 @@ async function handleExecuteCommand(command, socket, conversationRuntime, opts)
464248
464542
  error: error54,
464249
464543
  context: "listener_command_execution"
464250
464544
  });
464251
- const errorMessage2 = error54 instanceof Error ? error54.message : String(error54);
464545
+ const errorMessage3 = error54 instanceof Error ? error54.message : String(error54);
464252
464546
  emitSlashCommandEnd(socket, conversationRuntime, scope, {
464253
464547
  command_id: command.command_id,
464254
464548
  input,
464255
- output: `Failed: ${errorMessage2}`,
464549
+ output: `Failed: ${errorMessage3}`,
464256
464550
  success: false
464257
464551
  });
464258
464552
  emitExecuteCommandResponse(socket, command, {
464259
464553
  success: false,
464260
- output: `Failed: ${errorMessage2}`
464554
+ output: `Failed: ${errorMessage3}`
464261
464555
  });
464262
464556
  }
464263
464557
  }
@@ -466313,8 +466607,6 @@ function createListenerMessageHandler(params) {
466313
466607
  connectionId,
466314
466608
  agentId: parsed.runtime.agent_id,
466315
466609
  conversationId: parsed.runtime.conversation_id,
466316
- superRunId: parsed.runtime.super_run_id,
466317
- noCoalesce: parsed.runtime.super_run_id !== undefined,
466318
466610
  clientToolAllowlist: inputPayload.client_tool_allowlist,
466319
466611
  clientToolset: inputPayload.client_toolset,
466320
466612
  externalToolScopeIds: inputPayload.external_tool_scope_ids,
@@ -473868,8 +474160,168 @@ var init_mods = __esm(async () => {
473868
474160
  };
473869
474161
  });
473870
474162
 
473871
- // 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";
473872
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";
473873
474325
  function printAppServerHelp() {
473874
474326
  console.log(`Usage: letta server --listen [url]
473875
474327
 
@@ -473895,7 +474347,7 @@ Examples:
473895
474347
  letta server --listen ws://127.0.0.1:4500 --openai-api`);
473896
474348
  }
473897
474349
  async function waitForShutdown(close) {
473898
- return await new Promise((resolve33) => {
474350
+ return await new Promise((resolve34) => {
473899
474351
  let shuttingDown = false;
473900
474352
  const shutdown = (signal) => {
473901
474353
  if (shuttingDown)
@@ -473904,10 +474356,10 @@ async function waitForShutdown(close) {
473904
474356
  close().then(() => {
473905
474357
  console.log(`
473906
474358
  Stopped App Server (${signal}).`);
473907
- resolve33(0);
474359
+ resolve34(0);
473908
474360
  }).catch((error54) => {
473909
474361
  console.error(error54 instanceof Error ? `Error: ${error54.message}` : String(error54));
473910
- resolve33(1);
474362
+ resolve34(1);
473911
474363
  });
473912
474364
  };
473913
474365
  process.once("SIGINT", shutdown);
@@ -473917,7 +474369,7 @@ Stopped App Server (${signal}).`);
473917
474369
  async function runAppServerSubcommand(argv) {
473918
474370
  let parsed;
473919
474371
  try {
473920
- parsed = parseArgs13({
474372
+ parsed = parseArgs14({
473921
474373
  args: argv,
473922
474374
  allowPositionals: false,
473923
474375
  options: {
@@ -474469,7 +474921,7 @@ __export(exports_setup, {
474469
474921
  runSetup: () => runSetup
474470
474922
  });
474471
474923
  async function runSetup(options3 = {}) {
474472
- return new Promise((resolve33) => {
474924
+ return new Promise((resolve34) => {
474473
474925
  let settled = false;
474474
474926
  let instance2;
474475
474927
  const settle = (result) => {
@@ -474478,7 +474930,7 @@ async function runSetup(options3 = {}) {
474478
474930
  }
474479
474931
  settled = true;
474480
474932
  instance2.unmount();
474481
- resolve33(result);
474933
+ resolve34(result);
474482
474934
  };
474483
474935
  instance2 = render_default(import_react36.default.createElement(SetupUI, {
474484
474936
  initialMode: options3.initialMode,
@@ -474502,7 +474954,7 @@ var init_setup6 = __esm(async () => {
474502
474954
  });
474503
474955
 
474504
474956
  // src/cli/subcommands/setup.ts
474505
- function printUsage11() {
474957
+ function printUsage12() {
474506
474958
  console.log(`
474507
474959
  Usage:
474508
474960
  letta setup
@@ -474513,12 +474965,12 @@ Re-run the interactive setup menu to choose local mode or sign in with Letta.
474513
474965
  async function runSetupSubcommand(argv) {
474514
474966
  const [arg, ...rest3] = argv;
474515
474967
  if (arg === "help" || arg === "--help" || arg === "-h") {
474516
- printUsage11();
474968
+ printUsage12();
474517
474969
  return 0;
474518
474970
  }
474519
474971
  if (arg || rest3.length > 0) {
474520
474972
  console.error(`Unexpected arguments: ${[arg, ...rest3].filter(Boolean).join(" ")}`);
474521
- printUsage11();
474973
+ printUsage12();
474522
474974
  return 1;
474523
474975
  }
474524
474976
  await settingsManager.initialize();
@@ -474533,8 +474985,8 @@ var init_setup7 = __esm(async () => {
474533
474985
  // src/cli/subcommands/shared-memory.ts
474534
474986
  import { existsSync as existsSync57 } from "node:fs";
474535
474987
  import { join as join72 } from "node:path";
474536
- import { parseArgs as parseArgs14 } from "node:util";
474537
- function printUsage12() {
474988
+ import { parseArgs as parseArgs15 } from "node:util";
474989
+ function printUsage13() {
474538
474990
  console.log(`
474539
474991
  Usage:
474540
474992
  letta shared-memory list [--agent <id>]
@@ -474569,7 +475021,7 @@ Examples:
474569
475021
  `.trim());
474570
475022
  }
474571
475023
  function parseSharedMemoryArgs(argv) {
474572
- return parseArgs14({
475024
+ return parseArgs15({
474573
475025
  args: argv,
474574
475026
  options: SHARED_MEMORY_OPTIONS,
474575
475027
  strict: true,
@@ -474585,12 +475037,12 @@ function parseLimit4(value, fallback) {
474585
475037
  const parsed = Number.parseInt(value, 10);
474586
475038
  return Number.isNaN(parsed) || parsed <= 0 ? fallback : parsed;
474587
475039
  }
474588
- async function listOrgRepositories(request) {
475040
+ async function listOrgRepositories(request2) {
474589
475041
  const repositories = [];
474590
475042
  const limit3 = 50;
474591
475043
  let offset = 0;
474592
475044
  for (;; ) {
474593
- const page = await request("GET", `/v1/repositories?limit=${limit3}&offset=${offset}`);
475045
+ const page = await request2("GET", `/v1/repositories?limit=${limit3}&offset=${offset}`);
474594
475046
  repositories.push(...page.repositories);
474595
475047
  if (!page.has_next_page)
474596
475048
  break;
@@ -474598,8 +475050,8 @@ async function listOrgRepositories(request) {
474598
475050
  }
474599
475051
  return repositories;
474600
475052
  }
474601
- async function listAgentRepositories(request, agentId) {
474602
- 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`);
474603
475055
  return response.repositories.filter((repository) => !repository.is_primary && repository.name !== "memory");
474604
475056
  }
474605
475057
  function resolveRepositoryReference(repositories, reference) {
@@ -474608,9 +475060,9 @@ function resolveRepositoryReference(repositories, reference) {
474608
475060
  return null;
474609
475061
  return repositories.find((repository) => repository.id === trimmed) ?? repositories.find((repository) => repository.name === trimmed) ?? null;
474610
475062
  }
474611
- async function waitForAttachedRepository(request, agentId, repositoryId, poll) {
475063
+ async function waitForAttachedRepository(request2, agentId, repositoryId, poll) {
474612
475064
  for (let attempt = 0;attempt < poll.attempts; attempt += 1) {
474613
- const attached = await listAgentRepositories(request, agentId);
475065
+ const attached = await listAgentRepositories(request2, agentId);
474614
475066
  if (attached.some((repository) => repository.id === repositoryId)) {
474615
475067
  return true;
474616
475068
  }
@@ -474645,12 +475097,12 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
474645
475097
  parsed = parseSharedMemoryArgs(argv);
474646
475098
  } catch (error54) {
474647
475099
  console.error(error54 instanceof Error ? error54.message : String(error54));
474648
- printUsage12();
475100
+ printUsage13();
474649
475101
  return 1;
474650
475102
  }
474651
475103
  const [action3, reference] = parsed.positionals;
474652
475104
  if (parsed.values.help || !action3 || action3 === "help") {
474653
- printUsage12();
475105
+ printUsage13();
474654
475106
  return 0;
474655
475107
  }
474656
475108
  if (isLocalBackendEnvEnabled()) {
@@ -474658,16 +475110,16 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
474658
475110
  return 1;
474659
475111
  }
474660
475112
  await (deps.initializeSettings ?? (() => settingsManager.initialize()))();
474661
- const request = deps.request ?? apiRequest;
475113
+ const request2 = deps.request ?? apiRequest;
474662
475114
  const syncRepositories = deps.syncRepositories ?? syncAttachedAgentRepositories;
474663
475115
  const recompileAgent = deps.recompileAgent ?? defaultRecompileAgent;
474664
475116
  try {
474665
475117
  if (action3 === "list") {
474666
475118
  const agentId = resolveSharedMemoryAgentId(parsed.values.agent, parsed.values["agent-id"]);
474667
- const repositories = await listOrgRepositories(request);
475119
+ const repositories = await listOrgRepositories(request2);
474668
475120
  let attachedIds = new Set;
474669
475121
  if (agentId && !isLocalAgentId(agentId)) {
474670
- const attached = await listAgentRepositories(request, agentId);
475122
+ const attached = await listAgentRepositories(request2, agentId);
474671
475123
  attachedIds = new Set(attached.map((repository) => repository.id));
474672
475124
  }
474673
475125
  console.log(JSON.stringify({
@@ -474684,7 +475136,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
474684
475136
  console.error("Usage: letta shared-memory create --name <name>");
474685
475137
  return 1;
474686
475138
  }
474687
- const repository = await request("POST", "/v1/repositories", { name });
475139
+ const repository = await request2("POST", "/v1/repositories", { name });
474688
475140
  console.log(JSON.stringify(repository, null, 2));
474689
475141
  return 0;
474690
475142
  }
@@ -474693,7 +475145,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
474693
475145
  console.error(`Usage: letta shared-memory ${action3} <name-or-id>`);
474694
475146
  return 1;
474695
475147
  }
474696
- const repositories = await listOrgRepositories(request);
475148
+ const repositories = await listOrgRepositories(request2);
474697
475149
  const repository = resolveRepositoryReference(repositories, reference);
474698
475150
  if (!repository) {
474699
475151
  console.error(`Repository not found: ${reference}. Run \`letta shared-memory list\` to see available repositories.`);
@@ -474705,7 +475157,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
474705
475157
  if (parsed.values.path) {
474706
475158
  query2.set("path", parsed.values.path);
474707
475159
  }
474708
- 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}`);
474709
475161
  console.log(JSON.stringify({ repository: repository.name, ...versions2 }, null, 2));
474710
475162
  return 0;
474711
475163
  }
@@ -474713,8 +475165,8 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
474713
475165
  if (!agentId)
474714
475166
  return 1;
474715
475167
  if (action3 === "attach") {
474716
- await request("POST", `/v1/agents/${encodeURIComponent(agentId)}/repositories`, { repository_id: repository.id });
474717
- 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);
474718
475170
  if (!visible) {
474719
475171
  console.error(`Attach accepted but ${repository.name} did not appear in the agent's repository list. Retry \`letta shared-memory sync\` shortly.`);
474720
475172
  return 1;
@@ -474733,7 +475185,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
474733
475185
  }, null, 2));
474734
475186
  return mounted ? 0 : 1;
474735
475187
  }
474736
- await request("DELETE", `/v1/agents/${encodeURIComponent(agentId)}/repositories/${encodeURIComponent(repository.id)}`);
475188
+ await request2("DELETE", `/v1/agents/${encodeURIComponent(agentId)}/repositories/${encodeURIComponent(repository.id)}`);
474737
475189
  const detachRecompileError = await recompileAndReportFailure(recompileAgent, agentId);
474738
475190
  console.log(JSON.stringify({
474739
475191
  detached: true,
@@ -474752,7 +475204,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
474752
475204
  return result.failed > 0 ? 1 : 0;
474753
475205
  }
474754
475206
  console.error(`Unknown action: ${action3}`);
474755
- printUsage12();
475207
+ printUsage13();
474756
475208
  return 1;
474757
475209
  } catch (error54) {
474758
475210
  console.error(error54 instanceof Error ? error54.message : String(error54));
@@ -476258,9 +476710,9 @@ import {
476258
476710
  } from "node:fs";
476259
476711
  import { mkdir as mkdir15, readdir as readdir14 } from "node:fs/promises";
476260
476712
  import { tmpdir as tmpdir10 } from "node:os";
476261
- import { basename as basename28, dirname as dirname33, join as join73, normalize as normalize5, resolve as resolve33, sep as sep7 } from "node:path";
476262
- import { parseArgs as parseArgs15, TextDecoder as TextDecoder2, TextEncoder as TextEncoder2 } from "node:util";
476263
- 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() {
476264
476716
  console.log(`
476265
476717
  Usage:
476266
476718
  letta install <thing> [--agent <id> | -n <agent name>] [--force]
@@ -476287,7 +476739,7 @@ Options:
476287
476739
  `.trim());
476288
476740
  }
476289
476741
  function parseSkillsArgs(argv) {
476290
- return parseArgs15({
476742
+ return parseArgs16({
476291
476743
  args: argv,
476292
476744
  options: SKILLS_OPTIONS,
476293
476745
  strict: true,
@@ -476453,7 +476905,7 @@ function parseDirectSkillFileUrlSpecifier(input) {
476453
476905
  if (url2.protocol !== "https:" && !(url2.protocol === "http:" && isLocalhostHostname(url2.hostname))) {
476454
476906
  return null;
476455
476907
  }
476456
- if (basename28(url2.pathname).toLowerCase() !== "skill.md")
476908
+ if (basename29(url2.pathname).toLowerCase() !== "skill.md")
476457
476909
  return null;
476458
476910
  return { url: url2.toString() };
476459
476911
  }
@@ -476684,8 +477136,8 @@ async function downloadClawHubSkillSource(location) {
476684
477136
  return { tmpDir, sourceDir };
476685
477137
  }
476686
477138
  function assertInside(parent, child) {
476687
- const parentPath = resolve33(parent);
476688
- const childPath = resolve33(child);
477139
+ const parentPath = resolve34(parent);
477140
+ const childPath = resolve34(child);
476689
477141
  if (childPath !== parentPath && !childPath.startsWith(`${parentPath}${sep7}`)) {
476690
477142
  throw new Error(`Resolved path is outside target directory: ${child}`);
476691
477143
  }
@@ -476701,12 +477153,12 @@ function getSkillName(sourceDir) {
476701
477153
  const skillMd = readFileSync39(join73(sourceDir, "SKILL.md"), "utf8");
476702
477154
  const { frontmatter } = parseFrontmatter(skillMd);
476703
477155
  const frontmatterName = frontmatter.name;
476704
- const name = typeof frontmatterName === "string" && frontmatterName.trim() ? frontmatterName : basename28(sourceDir);
477156
+ const name = typeof frontmatterName === "string" && frontmatterName.trim() ? frontmatterName : basename29(sourceDir);
476705
477157
  return sanitizeSkillName(name);
476706
477158
  }
476707
477159
  async function installSkillDirectory(params) {
476708
- const sourceDir = resolve33(params.sourceDir);
476709
- const memoryDir = resolve33(params.memoryDir);
477160
+ const sourceDir = resolve34(params.sourceDir);
477161
+ const memoryDir = resolve34(params.memoryDir);
476710
477162
  const skillMdPath = join73(sourceDir, "SKILL.md");
476711
477163
  if (!existsSync58(skillMdPath)) {
476712
477164
  throw new Error("No SKILL.md found in the skill directory.");
@@ -476727,12 +477179,12 @@ async function installSkillDirectory(params) {
476727
477179
  await mkdir15(skillsDir, { recursive: true });
476728
477180
  cpSync2(sourceDir, targetPath, {
476729
477181
  recursive: true,
476730
- filter: (source2) => basename28(source2) !== ".git"
477182
+ filter: (source2) => basename29(source2) !== ".git"
476731
477183
  });
476732
477184
  return { name, path: normalize5(targetPath) };
476733
477185
  }
476734
477186
  async function listSkillDirectories(params) {
476735
- const memoryDir = resolve33(params.memoryDir);
477187
+ const memoryDir = resolve34(params.memoryDir);
476736
477188
  const skillsDir = join73(memoryDir, "skills");
476737
477189
  if (!existsSync58(skillsDir))
476738
477190
  return [];
@@ -476762,7 +477214,7 @@ async function listSkillDirectories(params) {
476762
477214
  return skills.sort((a2, b3) => a2.name.localeCompare(b3.name));
476763
477215
  }
476764
477216
  async function deleteSkillDirectory(params) {
476765
- const memoryDir = resolve33(params.memoryDir);
477217
+ const memoryDir = resolve34(params.memoryDir);
476766
477218
  const skillsDir = join73(memoryDir, "skills");
476767
477219
  const name = sanitizeSkillName(params.name);
476768
477220
  const targetPath = join73(skillsDir, name);
@@ -476814,7 +477266,7 @@ async function installSkill(specifier, agentId, force) {
476814
477266
  downloaded = await downloadClawHubSkillSource(source2.location);
476815
477267
  }
476816
477268
  tmpDir = downloaded.tmpDir;
476817
- const sourceDir = resolve33(downloaded.sourceDir);
477269
+ const sourceDir = resolve34(downloaded.sourceDir);
476818
477270
  assertInside(tmpDir, sourceDir);
476819
477271
  if (!existsSync58(sourceDir)) {
476820
477272
  const missingPath = source2.type === "git" ? source2.location.subdir ?? "." : source2.type === "direct-file" ? source2.location.url : source2.location.slug;
@@ -476935,17 +477387,17 @@ async function runInstall(argv, options3 = {}) {
476935
477387
  parsed = parseSkillsArgs(argv);
476936
477388
  } catch (error54) {
476937
477389
  console.error(`Error: ${error54 instanceof Error ? error54.message : String(error54)}`);
476938
- printUsage13();
477390
+ printUsage14();
476939
477391
  return 1;
476940
477392
  }
476941
477393
  const [specifier] = parsed.positionals;
476942
477394
  if (parsed.values.help || !specifier || specifier === "help") {
476943
- printUsage13();
477395
+ printUsage14();
476944
477396
  return 0;
476945
477397
  }
476946
477398
  if (parsed.positionals.length > 1) {
476947
477399
  console.error(`Unexpected argument: ${parsed.positionals[1]}`);
476948
- printUsage13();
477400
+ printUsage14();
476949
477401
  return 1;
476950
477402
  }
476951
477403
  if (specifier.startsWith("npm:")) {
@@ -476997,7 +477449,7 @@ async function runInstall(argv, options3 = {}) {
476997
477449
  return 1;
476998
477450
  }
476999
477451
  }
477000
- const maybeLocalPath = resolve33(specifier);
477452
+ const maybeLocalPath = resolve34(specifier);
477001
477453
  if (isLocalLettaModPackageDirectory(maybeLocalPath)) {
477002
477454
  if (hasInstallAgentScope(parsed.values)) {
477003
477455
  console.error("Agent-scoped mod package install is not supported yet.");
@@ -477036,16 +477488,16 @@ async function runList2(argv) {
477036
477488
  parsed = parseSkillsArgs(argv);
477037
477489
  } catch (error54) {
477038
477490
  console.error(`Error: ${error54 instanceof Error ? error54.message : String(error54)}`);
477039
- printUsage13();
477491
+ printUsage14();
477040
477492
  return 1;
477041
477493
  }
477042
477494
  if (parsed.values.help) {
477043
- printUsage13();
477495
+ printUsage14();
477044
477496
  return 0;
477045
477497
  }
477046
477498
  if (parsed.positionals.length > 0) {
477047
477499
  console.error(`Unexpected argument: ${parsed.positionals[0]}`);
477048
- printUsage13();
477500
+ printUsage14();
477049
477501
  return 1;
477050
477502
  }
477051
477503
  try {
@@ -477066,17 +477518,17 @@ async function runDelete(argv) {
477066
477518
  parsed = parseSkillsArgs(argv);
477067
477519
  } catch (error54) {
477068
477520
  console.error(`Error: ${error54 instanceof Error ? error54.message : String(error54)}`);
477069
- printUsage13();
477521
+ printUsage14();
477070
477522
  return 1;
477071
477523
  }
477072
477524
  const [skillName] = parsed.positionals;
477073
477525
  if (parsed.values.help || !skillName || skillName === "help") {
477074
- printUsage13();
477526
+ printUsage14();
477075
477527
  return 0;
477076
477528
  }
477077
477529
  if (parsed.positionals.length > 1) {
477078
477530
  console.error(`Unexpected argument: ${parsed.positionals[1]}`);
477079
- printUsage13();
477531
+ printUsage14();
477080
477532
  return 1;
477081
477533
  }
477082
477534
  const agentId = getExplicitAgentId2(parsed.values);
@@ -477116,11 +477568,11 @@ async function runSkillsSubcommand(argv) {
477116
477568
  case "help":
477117
477569
  case "--help":
477118
477570
  case "-h":
477119
- printUsage13();
477571
+ printUsage14();
477120
477572
  return 0;
477121
477573
  default:
477122
477574
  console.error(`Unknown action: ${action3}`);
477123
- printUsage13();
477575
+ printUsage14();
477124
477576
  return 1;
477125
477577
  }
477126
477578
  }
@@ -477139,26 +477591,26 @@ var init_skills4 = __esm(() => {
477139
477591
  });
477140
477592
 
477141
477593
  // src/cli/subcommands/trajectories/readers.ts
477142
- 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";
477143
477595
  import { join as join74 } from "node:path";
477144
477596
  async function loadSessionTranscript(item) {
477145
- const stats = await stat15(item.path);
477597
+ const stats = await stat16(item.path);
477146
477598
  if (stats.isDirectory()) {
477147
477599
  return assembleEventDirectory(item.path);
477148
477600
  }
477149
477601
  if (item.path.endsWith(".db")) {
477150
477602
  return exportHermesSession(item.path, item.id);
477151
477603
  }
477152
- return readFile25(item.path, "utf-8");
477604
+ return readFile26(item.path, "utf-8");
477153
477605
  }
477154
477606
  async function assembleEventDirectory(sessionDir) {
477155
477607
  const eventsSubdir = join74(sessionDir, "events");
477156
- const eventsDir = (await stat15(eventsSubdir).catch(() => null))?.isDirectory() ? eventsSubdir : sessionDir;
477608
+ const eventsDir = (await stat16(eventsSubdir).catch(() => null))?.isDirectory() ? eventsSubdir : sessionDir;
477157
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));
477158
477610
  if (names.length === 0) {
477159
477611
  throw new Error(`No event files found in ${eventsDir}`);
477160
477612
  }
477161
- 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"))));
477162
477614
  return JSON.stringify(events);
477163
477615
  }
477164
477616
  async function openReadOnlyDatabase(path46) {
@@ -477231,12 +477683,12 @@ import { createHash as createHash12 } from "node:crypto";
477231
477683
  import {
477232
477684
  mkdir as mkdir16,
477233
477685
  readdir as readdir16,
477234
- readFile as readFile26,
477686
+ readFile as readFile27,
477235
477687
  rm as rm10,
477236
- stat as stat16,
477237
- writeFile as writeFile18
477688
+ stat as stat17,
477689
+ writeFile as writeFile19
477238
477690
  } from "node:fs/promises";
477239
- import { basename as basename29, join as join75 } from "node:path";
477691
+ import { basename as basename30, join as join75 } from "node:path";
477240
477692
  function fileTimestamp(startedAt) {
477241
477693
  if (!startedAt)
477242
477694
  return "unknown-date";
@@ -477297,7 +477749,7 @@ function collectStats(records) {
477297
477749
  }
477298
477750
  async function prepareOutDir(outDir) {
477299
477751
  try {
477300
- const existing = await stat16(outDir);
477752
+ const existing = await stat17(outDir);
477301
477753
  if (!existing.isDirectory()) {
477302
477754
  throw new Error(`--out ${outDir} exists and is not a directory`);
477303
477755
  }
@@ -477356,7 +477808,7 @@ async function runTrajectoryExport(options3) {
477356
477808
  usedFiles.add(file3);
477357
477809
  const body3 = JSON.stringify(records);
477358
477810
  await mkdir16(join75(options3.outDir, source2), { recursive: true });
477359
- await writeFile18(join75(options3.outDir, file3), body3, "utf-8");
477811
+ await writeFile19(join75(options3.outDir, file3), body3, "utf-8");
477360
477812
  counts.exported += 1;
477361
477813
  manifest2.sessions.push({
477362
477814
  source: source2,
@@ -477404,13 +477856,13 @@ async function runTrajectoryExport(options3) {
477404
477856
  if (!supported.includes(explicit.source)) {
477405
477857
  throw new Error(`Unknown source "${explicit.source}" in --transcript. The installed trajectory package supports: ${supported.join(", ")}.`);
477406
477858
  }
477407
- 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"));
477408
477860
  }
477409
477861
  for (const checkpoint2 of options3.deepagents ?? []) {
477410
- await exportCheckpoint(checkpoint2, `${basename29(checkpoint2.path)}-${checkpoint2.threadId}`);
477862
+ await exportCheckpoint(checkpoint2, `${basename30(checkpoint2.path)}-${checkpoint2.threadId}`);
477411
477863
  }
477412
477864
  manifest2.sessions.sort((a2, b3) => (a2.startedAt ?? "").localeCompare(b3.startedAt ?? ""));
477413
- 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");
477414
477866
  return manifest2;
477415
477867
  }
477416
477868
  var MANIFEST_NAME = "manifest.json", FIRST_PROMPT_MAX_CHARS = 200, LIST_PAGE_LIMIT = 1000;
@@ -477421,12 +477873,12 @@ var init_export = __esm(() => {
477421
477873
  });
477422
477874
 
477423
477875
  // src/cli/subcommands/trajectories/review.ts
477424
- import { readFile as readFile27 } from "node:fs/promises";
477876
+ import { readFile as readFile28 } from "node:fs/promises";
477425
477877
  import { isAbsolute as isAbsolute27, join as join76 } from "node:path";
477426
477878
  async function readManifest(dir) {
477427
477879
  let raw2;
477428
477880
  try {
477429
- raw2 = await readFile27(join76(dir, "manifest.json"), "utf-8");
477881
+ raw2 = await readFile28(join76(dir, "manifest.json"), "utf-8");
477430
477882
  } catch {
477431
477883
  throw new Error(`No manifest at ${join76(dir, "manifest.json")}. Run: letta trajectories export --out ${dir}`);
477432
477884
  }
@@ -477439,7 +477891,7 @@ async function resolveSessionFile(dir, target2) {
477439
477891
  if (target2.endsWith(".json")) {
477440
477892
  const direct = isAbsolute27(target2) ? target2 : join76(dir, target2);
477441
477893
  try {
477442
- await readFile27(direct, "utf-8");
477894
+ await readFile28(direct, "utf-8");
477443
477895
  return direct;
477444
477896
  } catch {}
477445
477897
  }
@@ -477491,7 +477943,7 @@ async function searchSessions(dir, keyword, options3 = {}) {
477491
477943
  for (const session of filterSessions(manifest2.sessions, options3)) {
477492
477944
  let records;
477493
477945
  try {
477494
- records = JSON.parse(await readFile27(join76(dir, session.file), "utf-8"));
477946
+ records = JSON.parse(await readFile28(join76(dir, session.file), "utf-8"));
477495
477947
  } catch {
477496
477948
  continue;
477497
477949
  }
@@ -477522,9 +477974,9 @@ var TOOL_RESULT_MAX_CHARS = 500, REASONING_MAX_CHARS = 300, TOOL_ARGS_MAX_CHARS
477522
477974
  var init_review = () => {};
477523
477975
 
477524
477976
  // src/cli/subcommands/trajectories.ts
477525
- import { readFile as readFile28 } from "node:fs/promises";
477526
- import { parseArgs as parseArgs16 } from "node:util";
477527
- function printUsage14() {
477977
+ import { readFile as readFile29 } from "node:fs/promises";
477978
+ import { parseArgs as parseArgs17 } from "node:util";
477979
+ function printUsage15() {
477528
477980
  console.log(`
477529
477981
  Usage:
477530
477982
  letta trajectories export [options]
@@ -477629,7 +478081,7 @@ async function runView(flags, target2, options3) {
477629
478081
  return 1;
477630
478082
  }
477631
478083
  const path46 = await resolveSessionFile(flags.dir, target2);
477632
- const records = JSON.parse(await readFile28(path46, "utf-8"));
478084
+ const records = JSON.parse(await readFile29(path46, "utf-8"));
477633
478085
  console.log(renderSession(records, options3));
477634
478086
  return 0;
477635
478087
  }
@@ -477662,7 +478114,7 @@ ${results.length} session(s) matched "${keyword}"`);
477662
478114
  return 0;
477663
478115
  }
477664
478116
  function parseTrajectoriesArgs(argv) {
477665
- return parseArgs16({
478117
+ return parseArgs17({
477666
478118
  args: argv,
477667
478119
  options: TRAJECTORIES_OPTIONS,
477668
478120
  strict: true,
@@ -477675,12 +478127,12 @@ async function runTrajectoriesSubcommand(argv) {
477675
478127
  parsed = parseTrajectoriesArgs(argv);
477676
478128
  } catch (error54) {
477677
478129
  console.error(`Error: ${error54 instanceof Error ? error54.message : String(error54)}`);
477678
- printUsage14();
478130
+ printUsage15();
477679
478131
  return 1;
477680
478132
  }
477681
478133
  const [action3] = parsed.positionals;
477682
478134
  if (parsed.values.help || action3 === "help" || !action3) {
477683
- printUsage14();
478135
+ printUsage15();
477684
478136
  return parsed.values.help || action3 === "help" ? 0 : 1;
477685
478137
  }
477686
478138
  const asJson = Boolean(parsed.values.json);
@@ -477712,7 +478164,7 @@ async function runTrajectoriesSubcommand(argv) {
477712
478164
  }
477713
478165
  if (action3 !== "export") {
477714
478166
  console.error(`Unknown command: ${action3}`);
477715
- printUsage14();
478167
+ printUsage15();
477716
478168
  return 1;
477717
478169
  }
477718
478170
  const options3 = {
@@ -477855,7 +478307,7 @@ function waitForSocketOpen(socket) {
477855
478307
  if (socket.readyState === WEBSOCKET_OPEN_STATE) {
477856
478308
  return Promise.resolve();
477857
478309
  }
477858
- return new Promise((resolve34, reject) => {
478310
+ return new Promise((resolve35, reject) => {
477859
478311
  let detachOpen = () => {};
477860
478312
  let detachError = () => {};
477861
478313
  const cleanup = () => {
@@ -477864,7 +478316,7 @@ function waitForSocketOpen(socket) {
477864
478316
  };
477865
478317
  detachOpen = onceSocketEvent(socket, "open", () => {
477866
478318
  cleanup();
477867
- resolve34();
478319
+ resolve35();
477868
478320
  });
477869
478321
  detachError = onceSocketEvent(socket, "error", (event2) => {
477870
478322
  cleanup();
@@ -477977,13 +478429,13 @@ class AppServerClient {
477977
478429
  }
477978
478430
  requestRaw(command, options3) {
477979
478431
  const timeoutMs = options3.timeoutMs ?? this.requestTimeoutMs;
477980
- return new Promise((resolve34, reject) => {
478432
+ return new Promise((resolve35, reject) => {
477981
478433
  const timeout = setTimeout(() => {
477982
478434
  this.pending.delete(command.request_id);
477983
478435
  reject(new Error(`Timed out waiting for ${command.request_id}`));
477984
478436
  }, timeoutMs);
477985
478437
  this.pending.set(command.request_id, {
477986
- resolve: (message) => resolve34(message),
478438
+ resolve: (message) => resolve35(message),
477987
478439
  reject,
477988
478440
  predicate: options3.predicate,
477989
478441
  timeout
@@ -478006,13 +478458,13 @@ class AppServerClient {
478006
478458
  } : commandOrType;
478007
478459
  const options3 = isTypeRequest ? maybeOptions : bodyOrOptions;
478008
478460
  const timeoutMs = options3.timeoutMs ?? this.requestTimeoutMs;
478009
- return new Promise((resolve34, reject) => {
478461
+ return new Promise((resolve35, reject) => {
478010
478462
  const timeout = setTimeout(() => {
478011
478463
  this.pending.delete(command.request_id);
478012
478464
  reject(new Error(`Timed out waiting for ${command.request_id}`));
478013
478465
  }, timeoutMs);
478014
478466
  this.pending.set(command.request_id, {
478015
- resolve: (message) => resolve34(message),
478467
+ resolve: (message) => resolve35(message),
478016
478468
  reject,
478017
478469
  predicate: options3.predicate,
478018
478470
  timeout
@@ -478881,44 +479333,44 @@ function trimmedOrNull(value) {
478881
479333
  const trimmed = value?.trim();
478882
479334
  return trimmed ? trimmed : null;
478883
479335
  }
478884
- function effectiveTextThreadId(request, route) {
478885
- const requestThreadId = trimmedOrNull(request.threadId);
479336
+ function effectiveTextThreadId(request2, route) {
479337
+ const requestThreadId = trimmedOrNull(request2.threadId);
478886
479338
  const routeThreadId = trimmedOrNull(route.threadId);
478887
- if (request.channel === "telegram") {
479339
+ if (request2.channel === "telegram") {
478888
479340
  if (requestThreadId)
478889
479341
  return requestThreadId;
478890
479342
  if (route.chatType === "direct")
478891
479343
  return null;
478892
479344
  return route.chatId.trim().startsWith("-") ? routeThreadId : null;
478893
479345
  }
478894
- if (request.channel === "discord") {
479346
+ if (request2.channel === "discord") {
478895
479347
  return route.chatType === "direct" ? route.chatId : requestThreadId ?? routeThreadId;
478896
479348
  }
478897
- if (request.channel === "slack") {
478898
- const isDirect = route.chatType === "direct" || request.chatId.startsWith("D");
479349
+ if (request2.channel === "slack") {
479350
+ const isDirect = route.chatType === "direct" || request2.chatId.startsWith("D");
478899
479351
  if (isDirect)
478900
479352
  return requestThreadId ?? routeThreadId;
478901
- return request.replyToMessageId ? null : requestThreadId ?? routeThreadId;
479353
+ return request2.replyToMessageId ? null : requestThreadId ?? routeThreadId;
478902
479354
  }
478903
479355
  return null;
478904
479356
  }
478905
- function effectiveTextReplyId(request, route) {
478906
- const isSlackDirect = request.channel === "slack" && (route.chatType === "direct" || request.chatId.startsWith("D"));
478907
- 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);
478908
479360
  }
478909
- function messageIdempotencyKey(request, route) {
478910
- 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) {
478911
479363
  return null;
478912
479364
  }
478913
479365
  return JSON.stringify({
478914
- action: request.action,
478915
- channel: request.channel,
479366
+ action: request2.action,
479367
+ channel: request2.channel,
478916
479368
  chatId: route.chatId,
478917
479369
  accountId: route.accountId ?? null,
478918
479370
  chatType: route.chatType ?? null,
478919
- threadId: effectiveTextThreadId(request, route),
478920
- message: request.message ?? null,
478921
- replyToMessageId: effectiveTextReplyId(request, route)
479371
+ threadId: effectiveTextThreadId(request2, route),
479372
+ message: request2.message ?? null,
479373
+ replyToMessageId: effectiveTextReplyId(request2, route)
478922
479374
  });
478923
479375
  }
478924
479376
  async function executeMessageChannel(input, options3) {
@@ -478955,8 +479407,8 @@ async function executeMessageChannel(input, options3) {
478955
479407
  channelTurnSources: options3.channelTurnSources
478956
479408
  });
478957
479409
  const requestThreadId = normalized.action === "download-file" ? normalized.threadId : inferredThreadId ?? (normalized.channel === "telegram" && context4.route.chatType === "direct" ? normalized.threadId : context4.route.threadId ?? normalized.threadId);
478958
- const request2 = buildMessageChannelRequest(normalized, normalized.chatId, requestThreadId);
478959
- return await dispatchWithIdempotency(request2, context4, options3.idempotencyScope);
479410
+ const request3 = buildMessageChannelRequest(normalized, normalized.chatId, requestThreadId);
479411
+ return await dispatchWithIdempotency(request3, context4, options3.idempotencyScope);
478960
479412
  }
478961
479413
  if (normalized.channel !== "slack") {
478962
479414
  return `Error: Explicit MessageChannel targets are not supported on ${normalized.channel}.`;
@@ -478977,8 +479429,8 @@ async function executeMessageChannel(input, options3) {
478977
479429
  transport: proactive.transport,
478978
479430
  messageActions: proactive.messageActions
478979
479431
  };
478980
- const request = buildMessageChannelRequest(normalized, proactive.target.chatId, proactive.target.threadId);
478981
- 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);
478982
479434
  } catch (error54) {
478983
479435
  if (error54 instanceof MessageChannelDuplicateActionError)
478984
479436
  throw error54;
@@ -478989,9 +479441,9 @@ async function executeMessageChannel(input, options3) {
478989
479441
  async function executeMessageChannelExternalTool(input, options3) {
478990
479442
  return createMessageChannelExternalToolResult(await executeMessageChannel(input, options3));
478991
479443
  }
478992
- function dispatchWithIdempotency(request, context3, scope) {
478993
- const dispatch = () => dispatchMessageChannelAction({ request, context: context3 });
478994
- 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);
478995
479447
  return scope ? scope.execute(key2, dispatch) : dispatch();
478996
479448
  }
478997
479449
  var init_message_channel_executor = __esm(() => {
@@ -480027,7 +480479,7 @@ var init_progress_builder = __esm(() => {
480027
480479
  function runtimeKey(runtime) {
480028
480480
  return `${runtime.agent_id}:${runtime.conversation_id}`;
480029
480481
  }
480030
- function sourceKey(source2) {
480482
+ function sourceRouteKey(source2) {
480031
480483
  return [
480032
480484
  source2.channel,
480033
480485
  source2.accountId ?? "",
@@ -480035,12 +480487,26 @@ function sourceKey(source2) {
480035
480487
  source2.threadId ?? ""
480036
480488
  ].join(":");
480037
480489
  }
480038
- 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) {
480039
480499
  const byKey = new Map;
480040
480500
  for (const source2 of sources)
480041
- byKey.set(sourceKey(source2), source2);
480501
+ byKey.set(getKey(source2), source2);
480042
480502
  return [...byKey.values()];
480043
480503
  }
480504
+ function uniqueRoutedSources(sources) {
480505
+ return uniqueSourcesBy(sources, sourceRouteKey);
480506
+ }
480507
+ function uniqueLifecycleSources(sources) {
480508
+ return uniqueSourcesBy(sources, sourceLifecycleKey);
480509
+ }
480044
480510
  function channelTagsForSources(sources) {
480045
480511
  return [...new Set(sources.map((source2) => `channel:${source2.channel}`))];
480046
480512
  }
@@ -480070,11 +480536,11 @@ class ChannelGateway {
480070
480536
  constructor(client, hooks) {
480071
480537
  this.client = client;
480072
480538
  this.hooks = hooks;
480073
- this.disposers.push(client.onMessage((message) => this.handleMessage(message)), client.onExternalToolCall((request) => {
480074
- 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;
480075
480541
  const active = state?.active;
480076
- const sources = active?.sources ?? state?.routedSources ?? [];
480077
- return hooks.executeExternalTool(request, sources, active?.idempotencyScope ?? null);
480542
+ const sources = active?.routingSources ?? state?.routedSources ?? [];
480543
+ return hooks.executeExternalTool(request2, sources, active?.idempotencyScope ?? null);
480078
480544
  }));
480079
480545
  }
480080
480546
  close() {
@@ -480100,12 +480566,12 @@ class ChannelGateway {
480100
480566
  return true;
480101
480567
  }
480102
480568
  state.pendingSourcesByClientMessageId.set(delivery.clientMessageId, {
480103
- sources: uniqueSources(delivery.sources),
480569
+ sources: uniqueLifecycleSources(delivery.sources),
480104
480570
  disposition: "submitting"
480105
480571
  });
480106
480572
  try {
480107
480573
  await this.enqueueRegistration(async () => {
480108
- state.routedSources = uniqueSources([
480574
+ state.routedSources = uniqueRoutedSources([
480109
480575
  ...state.routedSources,
480110
480576
  ...delivery.sources
480111
480577
  ]);
@@ -480143,8 +480609,8 @@ class ChannelGateway {
480143
480609
  const pending = state.pendingSourcesByClientMessageId.get(delivery.clientMessageId);
480144
480610
  if (pending) {
480145
480611
  pending.disposition = "queued";
480146
- pending.acceptedAtQueueRevision = state.queueRevision;
480147
480612
  }
480613
+ this.reconcileExplicitQueueRemovals(state);
480148
480614
  }
480149
480615
  await Promise.all(queuedEvents);
480150
480616
  return true;
@@ -480160,7 +480626,8 @@ class ChannelGateway {
480160
480626
  if (!state.active) {
480161
480627
  recoveredTurn = {
480162
480628
  batchId: `channel-recovered-${crypto.randomUUID()}`,
480163
- sources: uniqueSources(sources),
480629
+ routingSources: uniqueRoutedSources(sources),
480630
+ lifecycleSources: uniqueLifecycleSources(sources),
480164
480631
  progress: createChannelTurnProgressBuilder(),
480165
480632
  richDraft: null,
480166
480633
  idempotencyScope: createMessageChannelIdempotencyScope()
@@ -480201,7 +480668,7 @@ class ChannelGateway {
480201
480668
  return result.accepted;
480202
480669
  }
480203
480670
  setRoutedSources(runtime, sources) {
480204
- this.getState(runtime).routedSources = uniqueSources(sources);
480671
+ this.getState(runtime).routedSources = uniqueRoutedSources(sources);
480205
480672
  }
480206
480673
  getKnownRuntimes() {
480207
480674
  return [...this.states.values()].map((state) => state.runtime);
@@ -480238,7 +480705,6 @@ class ChannelGateway {
480238
480705
  state = {
480239
480706
  runtime,
480240
480707
  pendingSourcesByClientMessageId: new Map,
480241
- queueRevision: 0,
480242
480708
  active: null,
480243
480709
  registrationSignature: null,
480244
480710
  registration: null,
@@ -480355,43 +480821,81 @@ class ChannelGateway {
480355
480821
  }
480356
480822
  handleQueueUpdate(message) {
480357
480823
  const state = this.getState(message.runtime);
480358
- state.queueRevision += 1;
480359
- const nextQueued = new Set(message.queue.map((entry) => entry.client_message_id));
480360
- 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 = [];
480361
480835
  for (const [
480362
480836
  clientMessageId,
480363
480837
  pending
480364
480838
  ] of state.pendingSourcesByClientMessageId) {
480365
- if (pending.disposition === "queued" && state.queueRevision > (pending.acceptedAtQueueRevision ?? -1) && !nextQueued.has(clientMessageId)) {
480366
- removed.push({ clientMessageId, sources: pending.sources });
480367
- state.pendingSourcesByClientMessageId.delete(clientMessageId);
480368
- }
480369
- }
480370
- if (!state.active && removed.length > 0) {
480371
- const first = removed[0];
480372
- if (first) {
480373
- this.activateSources(state, first.clientMessageId, removed.flatMap((entry) => entry.sources));
480839
+ if (pending.disposition !== "queued" || !pending.removalDisposition) {
480840
+ continue;
480374
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
+ }));
480375
480858
  }
480376
480859
  }
480377
480860
  activateSources(state, clientMessageId, sources) {
480378
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));
480379
480880
  return;
480380
480881
  }
480882
+ const routingSources = uniqueRoutedSources(sources);
480883
+ const lifecycleSources = uniqueLifecycleSources(sources);
480381
480884
  state.active = {
480382
480885
  batchId: `channel-${clientMessageId}`,
480383
- sources: uniqueSources(sources),
480886
+ routingSources,
480887
+ lifecycleSources,
480384
480888
  progress: createChannelTurnProgressBuilder(),
480385
480889
  richDraft: this.hooks.createRichDraft?.({
480386
480890
  batchId: `channel-${clientMessageId}`,
480387
- sources
480891
+ sources: routingSources
480388
480892
  }) ?? null,
480389
480893
  idempotencyScope: createMessageChannelIdempotencyScope()
480390
480894
  };
480391
480895
  const processingEvent = {
480392
480896
  type: "processing",
480393
480897
  batchId: state.active.batchId,
480394
- sources: state.active.sources
480898
+ sources: state.active.lifecycleSources
480395
480899
  };
480396
480900
  this.enqueueHook(state, () => this.hooks.onLifecycle(processingEvent));
480397
480901
  }
@@ -480409,7 +480913,7 @@ class ChannelGateway {
480409
480913
  this.enqueueHook(state, () => this.hooks.onProgress({
480410
480914
  type: "progress",
480411
480915
  batchId: active.batchId,
480412
- sources: active.sources,
480916
+ sources: active.routingSources,
480413
480917
  ...update2
480414
480918
  }));
480415
480919
  }
@@ -480429,7 +480933,7 @@ class ChannelGateway {
480429
480933
  this.enqueueHook(state, () => this.hooks.onLifecycle({
480430
480934
  type: "finished",
480431
480935
  batchId: active.batchId,
480432
- sources: active.sources,
480936
+ sources: active.lifecycleSources,
480433
480937
  outcome: lifecycleOutcome(terminal.stopReason),
480434
480938
  stopReason: terminal.stopReason,
480435
480939
  ...terminal.runId ?? active.runId ? { runId: terminal.runId ?? active.runId } : {},
@@ -480445,9 +480949,9 @@ class ChannelGateway {
480445
480949
  }));
480446
480950
  if (!state)
480447
480951
  return;
480448
- const sources = state.active?.sources ?? [];
480952
+ const sources = state.active?.routingSources ?? [];
480449
480953
  state.replayedControlRequestIds.add(message.request_id);
480450
- const sourceScopes = new Map(sources.map((source3) => [sourceKey(source3), source3]));
480954
+ const sourceScopes = new Map(sources.map((source3) => [sourceRouteKey(source3), source3]));
480451
480955
  if (sourceScopes.size !== 1)
480452
480956
  return;
480453
480957
  const source2 = [...sourceScopes.values()][0];
@@ -481700,12 +482204,12 @@ function createRoutedRuntimeRegistrationRefresher(options3) {
481700
482204
  });
481701
482205
  return run;
481702
482206
  };
481703
- const waitForRetry = () => new Promise((resolve34) => {
481704
- resolveRetry = resolve34;
482207
+ const waitForRetry = () => new Promise((resolve35) => {
482208
+ resolveRetry = resolve35;
481705
482209
  retryTimer = setTimeout(() => {
481706
482210
  retryTimer = null;
481707
482211
  resolveRetry = null;
481708
- resolve34();
482212
+ resolve35();
481709
482213
  }, retryDelayMs);
481710
482214
  retryTimer.unref?.();
481711
482215
  });
@@ -481870,16 +482374,16 @@ async function executeChannelServiceCommand(command) {
481870
482374
  await Promise.all(detachedTasks);
481871
482375
  return responses;
481872
482376
  }
481873
- async function executeGatewayServiceCommand(request) {
481874
- if (request.kind === "protocol") {
482377
+ async function executeGatewayServiceCommand(request2) {
482378
+ if (request2.kind === "protocol") {
481875
482379
  return {
481876
482380
  kind: "protocol",
481877
- messages: await executeChannelServiceCommand(request.command)
482381
+ messages: await executeChannelServiceCommand(request2.command)
481878
482382
  };
481879
482383
  }
481880
482384
  return {
481881
482385
  kind: "text",
481882
- text: await handleChannelsSlashCommand(request.runtime, request.args)
482386
+ text: await handleChannelsSlashCommand(request2.runtime, request2.args)
481883
482387
  };
481884
482388
  }
481885
482389
  function gatewayClientMessageId(delivery) {
@@ -481966,17 +482470,17 @@ async function startLocalChannelGateway(options3) {
481966
482470
  buildExternalTool: async (runtime) => {
481967
482471
  return buildGatewayMessageChannelTool(registry2.resolveTurnSourcesForScope(runtime.agent_id, runtime.conversation_id));
481968
482472
  },
481969
- executeExternalTool: async (request, sources, idempotencyScope) => {
481970
- if (request.tool_name !== "MessageChannel" || !request.runtime) {
481971
- 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}`);
481972
482476
  }
481973
482477
  return await executeLocalMessageChannelExternalTool({
481974
- ...request.input,
481975
- channel: String(request.input.channel ?? ""),
481976
- action: String(request.input.action ?? ""),
482478
+ ...request2.input,
482479
+ channel: String(request2.input.channel ?? ""),
482480
+ action: String(request2.input.action ?? ""),
481977
482481
  parentScope: {
481978
- agentId: request.runtime.agent_id,
481979
- conversationId: request.runtime.conversation_id
482482
+ agentId: request2.runtime.agent_id,
482483
+ conversationId: request2.runtime.conversation_id
481980
482484
  },
481981
482485
  channelTurnSources: sources
481982
482486
  }, idempotencyScope);
@@ -482285,14 +482789,14 @@ var exports_channel_gateway = {};
482285
482789
  __export(exports_channel_gateway, {
482286
482790
  runChannelGatewaySubcommand: () => runChannelGatewaySubcommand
482287
482791
  });
482288
- import { parseArgs as parseArgs17 } from "node:util";
482792
+ import { parseArgs as parseArgs18 } from "node:util";
482289
482793
  function isGatewayCommandEnvelope(value) {
482290
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");
482291
482795
  }
482292
482796
  async function runChannelGatewaySubcommand(argv) {
482293
482797
  let values2;
482294
482798
  try {
482295
- ({ values: values2 } = parseArgs17({
482799
+ ({ values: values2 } = parseArgs18({
482296
482800
  args: argv,
482297
482801
  strict: true,
482298
482802
  allowPositionals: false,
@@ -482331,7 +482835,7 @@ async function runChannelGatewaySubcommand(argv) {
482331
482835
  await ensureChannelRuntimeInstalled2(channelName);
482332
482836
  }
482333
482837
  }
482334
- return await new Promise((resolve34) => {
482838
+ return await new Promise((resolve35) => {
482335
482839
  let closing2 = false;
482336
482840
  let closeGateway = null;
482337
482841
  const finish = (code2) => {
@@ -482339,10 +482843,10 @@ async function runChannelGatewaySubcommand(argv) {
482339
482843
  return;
482340
482844
  closing2 = true;
482341
482845
  if (!closeGateway) {
482342
- resolve34(code2);
482846
+ resolve35(code2);
482343
482847
  return;
482344
482848
  }
482345
- closeGateway().finally(() => resolve34(code2));
482849
+ closeGateway().finally(() => resolve35(code2));
482346
482850
  };
482347
482851
  startLocalChannelGateway({
482348
482852
  appServerUrl,
@@ -482390,7 +482894,7 @@ async function runChannelGatewaySubcommand(argv) {
482390
482894
  gateway.close();
482391
482895
  }).catch((error54) => {
482392
482896
  console.error(error54 instanceof Error ? error54.message : String(error54));
482393
- resolve34(1);
482897
+ resolve35(1);
482394
482898
  });
482395
482899
  });
482396
482900
  }
@@ -482428,6 +482932,7 @@ function subcommandNeedsEarlyBackendMode(command) {
482428
482932
  case "messages":
482429
482933
  case "mods":
482430
482934
  case "remote":
482935
+ case "sandbox":
482431
482936
  case "server":
482432
482937
  case "shared-memory":
482433
482938
  case "skills":
@@ -482462,6 +482967,8 @@ async function runSubcommand(argv) {
482462
482967
  return runEnvironmentsSubcommand(rest3);
482463
482968
  case "mods":
482464
482969
  return runModsSubcommand(rest3);
482970
+ case "sandbox":
482971
+ return runSandboxSubcommand(rest3);
482465
482972
  case "server":
482466
482973
  return runServerSubcommand(rest3);
482467
482974
  case "remote":
@@ -482507,6 +483014,7 @@ var init_router = __esm(async () => {
482507
483014
  init_local_backend2();
482508
483015
  init_memory7();
482509
483016
  init_messages10();
483017
+ init_sandbox2();
482510
483018
  init_shared_memory();
482511
483019
  init_skills4();
482512
483020
  init_trajectories();
@@ -482584,10 +483092,10 @@ async function detectAndEnableKittyProtocol() {
482584
483092
  detectionComplete = true;
482585
483093
  return;
482586
483094
  }
482587
- return new Promise((resolve34) => {
483095
+ return new Promise((resolve35) => {
482588
483096
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
482589
483097
  detectionComplete = true;
482590
- resolve34();
483098
+ resolve35();
482591
483099
  return;
482592
483100
  }
482593
483101
  const originalRawMode = process.stdin.isRaw;
@@ -482620,7 +483128,7 @@ async function detectAndEnableKittyProtocol() {
482620
483128
  console.error("[kitty] protocol query unsupported; enabled anyway (best-effort)");
482621
483129
  }
482622
483130
  detectionComplete = true;
482623
- resolve34();
483131
+ resolve35();
482624
483132
  };
482625
483133
  const handleData = (data) => {
482626
483134
  if (timeoutId === undefined) {
@@ -483257,9 +483765,9 @@ function writeWireMessage(msg) {
483257
483765
  async function writeWireMessageAsync(msg) {
483258
483766
  const line = `${JSON.stringify(stampWireMessage(msg))}
483259
483767
  `;
483260
- return await new Promise((resolve34, reject) => {
483768
+ return await new Promise((resolve35, reject) => {
483261
483769
  if (process.stdout.destroyed || process.stdout.writableEnded) {
483262
- resolve34(false);
483770
+ resolve35(false);
483263
483771
  return;
483264
483772
  }
483265
483773
  process.stdout.write(line, (error54) => {
@@ -483267,7 +483775,7 @@ async function writeWireMessageAsync(msg) {
483267
483775
  reject(error54);
483268
483776
  return;
483269
483777
  }
483270
- resolve34(true);
483778
+ resolve35(true);
483271
483779
  });
483272
483780
  });
483273
483781
  }
@@ -484518,8 +485026,8 @@ async function parseErrorResponse2(input) {
484518
485026
  const errorClass = OAUTH_ERRORS[error54] || ServerError;
484519
485027
  return new errorClass(error_description || "", error_uri);
484520
485028
  } catch (error54) {
484521
- const errorMessage2 = `${statusCode2 ? `HTTP ${statusCode2}: ` : ""}Invalid OAuth error response: ${error54}. Raw body: ${body3}`;
484522
- return new ServerError(errorMessage2);
485029
+ const errorMessage3 = `${statusCode2 ? `HTTP ${statusCode2}: ` : ""}Invalid OAuth error response: ${error54}. Raw body: ${body3}`;
485030
+ return new ServerError(errorMessage3);
484523
485031
  }
484524
485032
  }
484525
485033
  async function auth(provider, options3) {
@@ -485150,8 +485658,8 @@ class Protocol {
485150
485658
  this._taskStore = _options?.taskStore;
485151
485659
  this._taskMessageQueue = _options?.taskMessageQueue;
485152
485660
  if (this._taskStore) {
485153
- this.setRequestHandler(GetTaskRequestSchema, async (request, extra) => {
485154
- 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);
485155
485663
  if (!task2) {
485156
485664
  throw new McpError(ErrorCode.InvalidParams, "Failed to retrieve task: Task not found");
485157
485665
  }
@@ -485159,9 +485667,9 @@ class Protocol {
485159
485667
  ...task2
485160
485668
  };
485161
485669
  });
485162
- this.setRequestHandler(GetTaskPayloadRequestSchema, async (request, extra) => {
485670
+ this.setRequestHandler(GetTaskPayloadRequestSchema, async (request2, extra) => {
485163
485671
  const handleTaskResult = async () => {
485164
- const taskId = request.params.taskId;
485672
+ const taskId = request2.params.taskId;
485165
485673
  if (this._taskMessageQueue) {
485166
485674
  let queuedMessage;
485167
485675
  while (queuedMessage = await this._taskMessageQueue.dequeue(taskId, extra.sessionId)) {
@@ -485174,8 +485682,8 @@ class Protocol {
485174
485682
  if (queuedMessage.type === "response") {
485175
485683
  resolver(message);
485176
485684
  } else {
485177
- const errorMessage2 = message;
485178
- 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);
485179
485687
  resolver(error54);
485180
485688
  }
485181
485689
  } else {
@@ -485212,9 +485720,9 @@ class Protocol {
485212
485720
  };
485213
485721
  return await handleTaskResult();
485214
485722
  });
485215
- this.setRequestHandler(ListTasksRequestSchema, async (request, extra) => {
485723
+ this.setRequestHandler(ListTasksRequestSchema, async (request2, extra) => {
485216
485724
  try {
485217
- 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);
485218
485726
  return {
485219
485727
  tasks: tasks2,
485220
485728
  nextCursor,
@@ -485224,20 +485732,20 @@ class Protocol {
485224
485732
  throw new McpError(ErrorCode.InvalidParams, `Failed to list tasks: ${error54 instanceof Error ? error54.message : String(error54)}`);
485225
485733
  }
485226
485734
  });
485227
- this.setRequestHandler(CancelTaskRequestSchema, async (request, extra) => {
485735
+ this.setRequestHandler(CancelTaskRequestSchema, async (request2, extra) => {
485228
485736
  try {
485229
- const task2 = await this._taskStore.getTask(request.params.taskId, extra.sessionId);
485737
+ const task2 = await this._taskStore.getTask(request2.params.taskId, extra.sessionId);
485230
485738
  if (!task2) {
485231
- throw new McpError(ErrorCode.InvalidParams, `Task not found: ${request.params.taskId}`);
485739
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${request2.params.taskId}`);
485232
485740
  }
485233
485741
  if (isTerminal(task2.status)) {
485234
485742
  throw new McpError(ErrorCode.InvalidParams, `Cannot cancel task in terminal status: ${task2.status}`);
485235
485743
  }
485236
- await this._taskStore.updateTaskStatus(request.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId);
485237
- this._clearTaskQueue(request.params.taskId);
485238
- 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);
485239
485747
  if (!cancelledTask) {
485240
- 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}`);
485241
485749
  }
485242
485750
  return {
485243
485751
  _meta: {},
@@ -485353,14 +485861,14 @@ class Protocol {
485353
485861
  }
485354
485862
  Promise.resolve().then(() => handler(notification)).catch((error54) => this._onerror(new Error(`Uncaught error in notification handler: ${error54}`)));
485355
485863
  }
485356
- _onrequest(request, extra) {
485357
- const handler = this._requestHandlers.get(request.method) ?? this.fallbackRequestHandler;
485864
+ _onrequest(request2, extra) {
485865
+ const handler = this._requestHandlers.get(request2.method) ?? this.fallbackRequestHandler;
485358
485866
  const capturedTransport = this._transport;
485359
- const relatedTaskId = request.params?._meta?.[RELATED_TASK_META_KEY]?.taskId;
485867
+ const relatedTaskId = request2.params?._meta?.[RELATED_TASK_META_KEY]?.taskId;
485360
485868
  if (handler === undefined) {
485361
485869
  const errorResponse = {
485362
485870
  jsonrpc: "2.0",
485363
- id: request.id,
485871
+ id: request2.id,
485364
485872
  error: {
485365
485873
  code: ErrorCode.MethodNotFound,
485366
485874
  message: "Method not found"
@@ -485378,17 +485886,17 @@ class Protocol {
485378
485886
  return;
485379
485887
  }
485380
485888
  const abortController = new AbortController;
485381
- this._requestHandlerAbortControllers.set(request.id, abortController);
485382
- const taskCreationParams = isTaskAugmentedRequestParams(request.params) ? request.params.task : undefined;
485383
- 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;
485384
485892
  const fullExtra = {
485385
485893
  signal: abortController.signal,
485386
485894
  sessionId: capturedTransport?.sessionId,
485387
- _meta: request.params?._meta,
485895
+ _meta: request2.params?._meta,
485388
485896
  sendNotification: async (notification) => {
485389
485897
  if (abortController.signal.aborted)
485390
485898
  return;
485391
- const notificationOptions = { relatedRequestId: request.id };
485899
+ const notificationOptions = { relatedRequestId: request2.id };
485392
485900
  if (relatedTaskId) {
485393
485901
  notificationOptions.relatedTask = { taskId: relatedTaskId };
485394
485902
  }
@@ -485398,7 +485906,7 @@ class Protocol {
485398
485906
  if (abortController.signal.aborted) {
485399
485907
  throw new McpError(ErrorCode.ConnectionClosed, "Request was cancelled");
485400
485908
  }
485401
- const requestOptions = { ...options3, relatedRequestId: request.id };
485909
+ const requestOptions = { ...options3, relatedRequestId: request2.id };
485402
485910
  if (relatedTaskId && !requestOptions.relatedTask) {
485403
485911
  requestOptions.relatedTask = { taskId: relatedTaskId };
485404
485912
  }
@@ -485409,7 +485917,7 @@ class Protocol {
485409
485917
  return await this.request(r5, resultSchema, requestOptions);
485410
485918
  },
485411
485919
  authInfo: extra?.authInfo,
485412
- requestId: request.id,
485920
+ requestId: request2.id,
485413
485921
  requestInfo: extra?.requestInfo,
485414
485922
  taskId: relatedTaskId,
485415
485923
  taskStore,
@@ -485419,16 +485927,16 @@ class Protocol {
485419
485927
  };
485420
485928
  Promise.resolve().then(() => {
485421
485929
  if (taskCreationParams) {
485422
- this.assertTaskHandlerCapability(request.method);
485930
+ this.assertTaskHandlerCapability(request2.method);
485423
485931
  }
485424
- }).then(() => handler(request, fullExtra)).then(async (result) => {
485932
+ }).then(() => handler(request2, fullExtra)).then(async (result) => {
485425
485933
  if (abortController.signal.aborted) {
485426
485934
  return;
485427
485935
  }
485428
485936
  const response = {
485429
485937
  result,
485430
485938
  jsonrpc: "2.0",
485431
- id: request.id
485939
+ id: request2.id
485432
485940
  };
485433
485941
  if (relatedTaskId && this._taskMessageQueue) {
485434
485942
  await this._enqueueTaskMessage(relatedTaskId, {
@@ -485445,7 +485953,7 @@ class Protocol {
485445
485953
  }
485446
485954
  const errorResponse = {
485447
485955
  jsonrpc: "2.0",
485448
- id: request.id,
485956
+ id: request2.id,
485449
485957
  error: {
485450
485958
  code: Number.isSafeInteger(error54["code"]) ? error54["code"] : ErrorCode.InternalError,
485451
485959
  message: error54.message ?? "Internal error",
@@ -485462,8 +485970,8 @@ class Protocol {
485462
485970
  await capturedTransport?.send(errorResponse);
485463
485971
  }
485464
485972
  }).catch((error54) => this._onerror(new Error(`Failed to send response: ${error54}`))).finally(() => {
485465
- if (this._requestHandlerAbortControllers.get(request.id) === abortController) {
485466
- this._requestHandlerAbortControllers.delete(request.id);
485973
+ if (this._requestHandlerAbortControllers.get(request2.id) === abortController) {
485974
+ this._requestHandlerAbortControllers.delete(request2.id);
485467
485975
  }
485468
485976
  });
485469
485977
  }
@@ -485537,11 +486045,11 @@ class Protocol {
485537
486045
  async close() {
485538
486046
  await this._transport?.close();
485539
486047
  }
485540
- async* requestStream(request, resultSchema, options3) {
486048
+ async* requestStream(request2, resultSchema, options3) {
485541
486049
  const { task: task2 } = options3 ?? {};
485542
486050
  if (!task2) {
485543
486051
  try {
485544
- const result = await this.request(request, resultSchema, options3);
486052
+ const result = await this.request(request2, resultSchema, options3);
485545
486053
  yield { type: "result", result };
485546
486054
  } catch (error54) {
485547
486055
  yield {
@@ -485553,7 +486061,7 @@ class Protocol {
485553
486061
  }
485554
486062
  let taskId;
485555
486063
  try {
485556
- const createResult = await this.request(request, CreateTaskResultSchema, options3);
486064
+ const createResult = await this.request(request2, CreateTaskResultSchema, options3);
485557
486065
  if (createResult.task) {
485558
486066
  taskId = createResult.task.taskId;
485559
486067
  yield { type: "taskCreated", task: createResult.task };
@@ -485586,7 +486094,7 @@ class Protocol {
485586
486094
  return;
485587
486095
  }
485588
486096
  const pollInterval = task3.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1000;
485589
- await new Promise((resolve34) => setTimeout(resolve34, pollInterval));
486097
+ await new Promise((resolve35) => setTimeout(resolve35, pollInterval));
485590
486098
  options3?.signal?.throwIfAborted();
485591
486099
  }
485592
486100
  } catch (error54) {
@@ -485596,9 +486104,9 @@ class Protocol {
485596
486104
  };
485597
486105
  }
485598
486106
  }
485599
- request(request, resultSchema, options3) {
486107
+ request(request2, resultSchema, options3) {
485600
486108
  const { relatedRequestId, resumptionToken, onresumptiontoken, task: task2, relatedTask } = options3 ?? {};
485601
- return new Promise((resolve34, reject) => {
486109
+ return new Promise((resolve35, reject) => {
485602
486110
  const earlyReject = (error54) => {
485603
486111
  reject(error54);
485604
486112
  };
@@ -485608,9 +486116,9 @@ class Protocol {
485608
486116
  }
485609
486117
  if (this._options?.enforceStrictCapabilities === true) {
485610
486118
  try {
485611
- this.assertCapabilityForMethod(request.method);
486119
+ this.assertCapabilityForMethod(request2.method);
485612
486120
  if (task2) {
485613
- this.assertTaskCapability(request.method);
486121
+ this.assertTaskCapability(request2.method);
485614
486122
  }
485615
486123
  } catch (e2) {
485616
486124
  earlyReject(e2);
@@ -485620,16 +486128,16 @@ class Protocol {
485620
486128
  options3?.signal?.throwIfAborted();
485621
486129
  const messageId2 = this._requestMessageId++;
485622
486130
  const jsonrpcRequest = {
485623
- ...request,
486131
+ ...request2,
485624
486132
  jsonrpc: "2.0",
485625
486133
  id: messageId2
485626
486134
  };
485627
486135
  if (options3?.onprogress) {
485628
486136
  this._progressHandlers.set(messageId2, options3.onprogress);
485629
486137
  jsonrpcRequest.params = {
485630
- ...request.params,
486138
+ ...request2.params,
485631
486139
  _meta: {
485632
- ...request.params?._meta || {},
486140
+ ...request2.params?._meta || {},
485633
486141
  progressToken: messageId2
485634
486142
  }
485635
486143
  };
@@ -485676,7 +486184,7 @@ class Protocol {
485676
486184
  if (!parseResult.success) {
485677
486185
  reject(parseResult.error);
485678
486186
  } else {
485679
- resolve34(parseResult.data);
486187
+ resolve35(parseResult.data);
485680
486188
  }
485681
486189
  } catch (error54) {
485682
486190
  reject(error54);
@@ -485805,8 +486313,8 @@ class Protocol {
485805
486313
  setRequestHandler(requestSchema, handler) {
485806
486314
  const method = getMethodLiteral(requestSchema);
485807
486315
  this.assertRequestHandlerCapability(method);
485808
- this._requestHandlers.set(method, (request, extra) => {
485809
- const parsed = parseWithCompat(requestSchema, request);
486316
+ this._requestHandlers.set(method, (request2, extra) => {
486317
+ const parsed = parseWithCompat(requestSchema, request2);
485810
486318
  return Promise.resolve(handler(parsed, extra));
485811
486319
  });
485812
486320
  }
@@ -485867,31 +486375,31 @@ class Protocol {
485867
486375
  interval = task2.pollInterval;
485868
486376
  }
485869
486377
  } catch {}
485870
- return new Promise((resolve34, reject) => {
486378
+ return new Promise((resolve35, reject) => {
485871
486379
  if (signal.aborted) {
485872
486380
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
485873
486381
  return;
485874
486382
  }
485875
- const timeoutId = setTimeout(resolve34, interval);
486383
+ const timeoutId = setTimeout(resolve35, interval);
485876
486384
  signal.addEventListener("abort", () => {
485877
486385
  clearTimeout(timeoutId);
485878
486386
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
485879
486387
  }, { once: true });
485880
486388
  });
485881
486389
  }
485882
- requestTaskStore(request, sessionId) {
486390
+ requestTaskStore(request2, sessionId) {
485883
486391
  const taskStore = this._taskStore;
485884
486392
  if (!taskStore) {
485885
486393
  throw new Error("No task store configured");
485886
486394
  }
485887
486395
  return {
485888
486396
  createTask: async (taskParams) => {
485889
- if (!request) {
486397
+ if (!request2) {
485890
486398
  throw new Error("No request provided");
485891
486399
  }
485892
- return await taskStore.createTask(taskParams, request.id, {
485893
- method: request.method,
485894
- params: request.params
486400
+ return await taskStore.createTask(taskParams, request2.id, {
486401
+ method: request2.method,
486402
+ params: request2.params
485895
486403
  }, sessionId);
485896
486404
  },
485897
486405
  getTask: async (taskId) => {
@@ -488857,7 +489365,7 @@ var require_compile = __commonJS((exports) => {
488857
489365
  const schOrFunc = root2.refs[ref6];
488858
489366
  if (schOrFunc)
488859
489367
  return schOrFunc;
488860
- let _sch = resolve34.call(this, root2, ref6);
489368
+ let _sch = resolve35.call(this, root2, ref6);
488861
489369
  if (_sch === undefined) {
488862
489370
  const schema5 = (_a8 = root2.localRefs) === null || _a8 === undefined ? undefined : _a8[ref6];
488863
489371
  const { schemaId } = this.opts;
@@ -488884,7 +489392,7 @@ var require_compile = __commonJS((exports) => {
488884
489392
  function sameSchemaEnv(s1, s22) {
488885
489393
  return s1.schema === s22.schema && s1.root === s22.root && s1.baseId === s22.baseId;
488886
489394
  }
488887
- function resolve34(root2, ref6) {
489395
+ function resolve35(root2, ref6) {
488888
489396
  let sch;
488889
489397
  while (typeof (sch = this.refs[ref6]) == "string")
488890
489398
  ref6 = sch;
@@ -489470,7 +489978,7 @@ var require_fast_uri = __commonJS((exports, module3) => {
489470
489978
  }
489471
489979
  return uri;
489472
489980
  }
489473
- function resolve34(baseURI, relativeURI, options3) {
489981
+ function resolve35(baseURI, relativeURI, options3) {
489474
489982
  const schemelessOptions = options3 ? Object.assign({ scheme: "null" }, options3) : { scheme: "null" };
489475
489983
  const resolved = resolveComponent(parse9(baseURI, schemelessOptions), parse9(relativeURI, schemelessOptions), schemelessOptions, true);
489476
489984
  schemelessOptions.skipEscape = true;
@@ -489735,7 +490243,7 @@ var require_fast_uri = __commonJS((exports, module3) => {
489735
490243
  var fastUri = {
489736
490244
  SCHEMES,
489737
490245
  normalize: normalize6,
489738
- resolve: resolve34,
490246
+ resolve: resolve35,
489739
490247
  resolveComponent,
489740
490248
  equal: equal3,
489741
490249
  serialize,
@@ -492640,8 +493148,8 @@ class ExperimentalClientTasks {
492640
493148
  async cancelTask(taskId, options3) {
492641
493149
  return this._client.cancelTask({ taskId }, options3);
492642
493150
  }
492643
- requestStream(request, resultSchema, options3) {
492644
- return this._client.requestStream(request, resultSchema, options3);
493151
+ requestStream(request2, resultSchema, options3) {
493152
+ return this._client.requestStream(request2, resultSchema, options3);
492645
493153
  }
492646
493154
  }
492647
493155
  var init_client8 = __esm(() => {
@@ -492792,11 +493300,11 @@ var init_client9 = __esm(() => {
492792
493300
  }
492793
493301
  const method = methodValue;
492794
493302
  if (method === "elicitation/create") {
492795
- const wrappedHandler = async (request, extra) => {
492796
- const validatedRequest = safeParse4(ElicitRequestSchema, request);
493303
+ const wrappedHandler = async (request2, extra) => {
493304
+ const validatedRequest = safeParse4(ElicitRequestSchema, request2);
492797
493305
  if (!validatedRequest.success) {
492798
- const errorMessage2 = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
492799
- 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}`);
492800
493308
  }
492801
493309
  const { params } = validatedRequest.data;
492802
493310
  params.mode = params.mode ?? "form";
@@ -492807,19 +493315,19 @@ var init_client9 = __esm(() => {
492807
493315
  if (params.mode === "url" && !supportsUrlMode) {
492808
493316
  throw new McpError(ErrorCode.InvalidParams, "Client does not support URL-mode elicitation requests");
492809
493317
  }
492810
- const result = await Promise.resolve(handler(request, extra));
493318
+ const result = await Promise.resolve(handler(request2, extra));
492811
493319
  if (params.task) {
492812
493320
  const taskValidationResult = safeParse4(CreateTaskResultSchema, result);
492813
493321
  if (!taskValidationResult.success) {
492814
- const errorMessage2 = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
492815
- 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}`);
492816
493324
  }
492817
493325
  return taskValidationResult.data;
492818
493326
  }
492819
493327
  const validationResult = safeParse4(ElicitResultSchema, result);
492820
493328
  if (!validationResult.success) {
492821
- const errorMessage2 = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
492822
- 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}`);
492823
493331
  }
492824
493332
  const validatedResult = validationResult.data;
492825
493333
  const requestedSchema = params.mode === "form" ? params.requestedSchema : undefined;
@@ -492835,19 +493343,19 @@ var init_client9 = __esm(() => {
492835
493343
  return super.setRequestHandler(requestSchema, wrappedHandler);
492836
493344
  }
492837
493345
  if (method === "sampling/createMessage") {
492838
- const wrappedHandler = async (request, extra) => {
492839
- const validatedRequest = safeParse4(CreateMessageRequestSchema, request);
493346
+ const wrappedHandler = async (request2, extra) => {
493347
+ const validatedRequest = safeParse4(CreateMessageRequestSchema, request2);
492840
493348
  if (!validatedRequest.success) {
492841
- const errorMessage2 = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
492842
- 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}`);
492843
493351
  }
492844
493352
  const { params } = validatedRequest.data;
492845
- const result = await Promise.resolve(handler(request, extra));
493353
+ const result = await Promise.resolve(handler(request2, extra));
492846
493354
  if (params.task) {
492847
493355
  const taskValidationResult = safeParse4(CreateTaskResultSchema, result);
492848
493356
  if (!taskValidationResult.success) {
492849
- const errorMessage2 = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
492850
- 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}`);
492851
493359
  }
492852
493360
  return taskValidationResult.data;
492853
493361
  }
@@ -492855,8 +493363,8 @@ var init_client9 = __esm(() => {
492855
493363
  const resultSchema = hasTools ? CreateMessageResultWithToolsSchema : CreateMessageResultSchema;
492856
493364
  const validationResult = safeParse4(resultSchema, result);
492857
493365
  if (!validationResult.success) {
492858
- const errorMessage2 = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
492859
- 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}`);
492860
493368
  }
492861
493369
  return validationResult.data;
492862
493370
  };
@@ -493554,7 +494062,7 @@ class SSEClientTransport {
493554
494062
  }
493555
494063
  _startOrAuth() {
493556
494064
  const fetchImpl = this?._eventSourceInit?.fetch ?? this._fetch ?? fetch;
493557
- return new Promise((resolve34, reject) => {
494065
+ return new Promise((resolve35, reject) => {
493558
494066
  this._eventSource = new EventSource2(this._url.href, {
493559
494067
  ...this._eventSourceInit,
493560
494068
  fetch: async (url2, init) => {
@@ -493575,7 +494083,7 @@ class SSEClientTransport {
493575
494083
  this._abortController = new AbortController;
493576
494084
  this._eventSource.onerror = (event2) => {
493577
494085
  if (event2.code === 401 && this._authProvider) {
493578
- this._authThenStart().then(resolve34, reject);
494086
+ this._authThenStart().then(resolve35, reject);
493579
494087
  return;
493580
494088
  }
493581
494089
  const error54 = new SseError(event2.code, event2.message, event2);
@@ -493596,7 +494104,7 @@ class SSEClientTransport {
493596
494104
  this.close();
493597
494105
  return;
493598
494106
  }
493599
- resolve34();
494107
+ resolve35();
493600
494108
  });
493601
494109
  this._eventSource.onmessage = (event2) => {
493602
494110
  const messageEvent2 = event2;
@@ -493769,7 +494277,7 @@ class StdioClientTransport {
493769
494277
  if (this._process) {
493770
494278
  throw new Error("StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.");
493771
494279
  }
493772
- return new Promise((resolve34, reject) => {
494280
+ return new Promise((resolve35, reject) => {
493773
494281
  this._process = import_cross_spawn2.default(this._serverParams.command, this._serverParams.args ?? [], {
493774
494282
  env: {
493775
494283
  ...getDefaultEnvironment(),
@@ -493785,7 +494293,7 @@ class StdioClientTransport {
493785
494293
  this.onerror?.(error54);
493786
494294
  });
493787
494295
  this._process.on("spawn", () => {
493788
- resolve34();
494296
+ resolve35();
493789
494297
  });
493790
494298
  this._process.on("close", (_code) => {
493791
494299
  this._process = undefined;
@@ -493837,20 +494345,20 @@ class StdioClientTransport {
493837
494345
  if (this._process) {
493838
494346
  const processToClose = this._process;
493839
494347
  this._process = undefined;
493840
- const closePromise = new Promise((resolve34) => {
494348
+ const closePromise = new Promise((resolve35) => {
493841
494349
  processToClose.once("close", () => {
493842
- resolve34();
494350
+ resolve35();
493843
494351
  });
493844
494352
  });
493845
494353
  try {
493846
494354
  processToClose.stdin?.end();
493847
494355
  } catch {}
493848
- await Promise.race([closePromise, new Promise((resolve34) => setTimeout(resolve34, 2000).unref())]);
494356
+ await Promise.race([closePromise, new Promise((resolve35) => setTimeout(resolve35, 2000).unref())]);
493849
494357
  if (processToClose.exitCode === null) {
493850
494358
  try {
493851
494359
  processToClose.kill("SIGTERM");
493852
494360
  } catch {}
493853
- await Promise.race([closePromise, new Promise((resolve34) => setTimeout(resolve34, 2000).unref())]);
494361
+ await Promise.race([closePromise, new Promise((resolve35) => setTimeout(resolve35, 2000).unref())]);
493854
494362
  }
493855
494363
  if (processToClose.exitCode === null) {
493856
494364
  try {
@@ -493861,15 +494369,15 @@ class StdioClientTransport {
493861
494369
  this._readBuffer.clear();
493862
494370
  }
493863
494371
  send(message) {
493864
- return new Promise((resolve34) => {
494372
+ return new Promise((resolve35) => {
493865
494373
  if (!this._process?.stdin) {
493866
494374
  throw new Error("Not connected");
493867
494375
  }
493868
494376
  const json3 = serializeMessage(message);
493869
494377
  if (this._process.stdin.write(json3)) {
493870
- resolve34();
494378
+ resolve35();
493871
494379
  } else {
493872
- this._process.stdin.once("drain", resolve34);
494380
+ this._process.stdin.once("drain", resolve35);
493873
494381
  }
493874
494382
  });
493875
494383
  }
@@ -494545,7 +495053,7 @@ var init_mcp_client = __esm(() => {
494545
495053
  init_streamableHttp();
494546
495054
  DEFAULT_CLIENT_INFO = {
494547
495055
  name: "letta-code",
494548
- version: "0.30.17"
495056
+ version: "0.30.19"
494549
495057
  };
494550
495058
  });
494551
495059
 
@@ -494690,10 +495198,10 @@ async function startOAuthCallbackServerOnPort(port) {
494690
495198
  let completed = false;
494691
495199
  let settle;
494692
495200
  let reject;
494693
- const codePromise = new Promise((resolve34, rejectPromise) => {
495201
+ const codePromise = new Promise((resolve35, rejectPromise) => {
494694
495202
  settle = (code2) => {
494695
495203
  completed = true;
494696
- resolve34(code2);
495204
+ resolve35(code2);
494697
495205
  };
494698
495206
  reject = (error54) => {
494699
495207
  completed = true;
@@ -494703,8 +495211,8 @@ async function startOAuthCallbackServerOnPort(port) {
494703
495211
  codePromise.catch(() => {
494704
495212
  return;
494705
495213
  });
494706
- server2 = createServer3((request, response) => {
494707
- 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");
494708
495216
  if (url2.pathname !== "/callback") {
494709
495217
  response.writeHead(404).end("Not found");
494710
495218
  return;
@@ -494731,9 +495239,9 @@ async function startOAuthCallbackServerOnPort(port) {
494731
495239
  settle?.(code2);
494732
495240
  server2.close();
494733
495241
  });
494734
- await new Promise((resolve34, rejectListen) => {
495242
+ await new Promise((resolve35, rejectListen) => {
494735
495243
  server2.once("error", rejectListen);
494736
- server2.listen(port, "127.0.0.1", resolve34);
495244
+ server2.listen(port, "127.0.0.1", resolve35);
494737
495245
  });
494738
495246
  server2.unref();
494739
495247
  const address = server2.address();
@@ -494968,7 +495476,7 @@ var init_mcp_runtime = __esm(async () => {
494968
495476
 
494969
495477
  // src/skills/builtin/creating-skills/scripts/validate-skill.ts
494970
495478
  import { existsSync as existsSync61, readFileSync as readFileSync40 } from "node:fs";
494971
- 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";
494972
495480
  import { fileURLToPath as fileURLToPath11 } from "node:url";
494973
495481
  function parseQuotedScalar(value) {
494974
495482
  if (value.startsWith('"')) {
@@ -495128,7 +495636,7 @@ function validateSkill(skillPath) {
495128
495636
  message: `Name is too long (${trimmedName.length} characters). Maximum is ${MAX_SKILL_NAME_LENGTH} characters.`
495129
495637
  };
495130
495638
  }
495131
- const dirName = basename30(skillPath);
495639
+ const dirName = basename31(skillPath);
495132
495640
  if (trimmedName !== dirName) {
495133
495641
  warnings.push(`Name '${trimmedName}' doesn't match directory name '${dirName}'. For portability, these should match.`);
495134
495642
  }
@@ -495163,7 +495671,7 @@ function validateSkill(skillPath) {
495163
495671
  }
495164
495672
  function isMainModule() {
495165
495673
  const entrypoint = process.argv[1];
495166
- return entrypoint ? resolve34(entrypoint) === fileURLToPath11(import.meta.url) : false;
495674
+ return entrypoint ? resolve35(entrypoint) === fileURLToPath11(import.meta.url) : false;
495167
495675
  }
495168
495676
  var ALLOWED_PROPERTIES, MAX_SKILL_NAME_LENGTH = 64;
495169
495677
  var init_validate_skill = __esm(() => {
@@ -495232,8 +495740,8 @@ __export(exports_import, {
495232
495740
  extractSkillsFromAf: () => extractSkillsFromAf
495233
495741
  });
495234
495742
  import { createReadStream as createReadStream2 } from "node:fs";
495235
- import { access as access2, chmod, mkdir as mkdir17, readFile as readFile29, writeFile as writeFile19 } from "node:fs/promises";
495236
- 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";
495237
495745
  function validateImportedSkillName(name) {
495238
495746
  const trimmedName = name.trim();
495239
495747
  if (trimmedName !== name || trimmedName.length === 0 || trimmedName.length > MAX_SKILL_NAME_LENGTH || trimmedName === "." || trimmedName === ".." || !IMPORTED_SKILL_NAME_PATTERN.test(trimmedName)) {
@@ -495242,8 +495750,8 @@ function validateImportedSkillName(name) {
495242
495750
  return trimmedName;
495243
495751
  }
495244
495752
  function assertPathInside(parent, child) {
495245
- const parentPath = resolve35(parent);
495246
- const childPath = resolve35(child);
495753
+ const parentPath = resolve36(parent);
495754
+ const childPath = resolve36(child);
495247
495755
  const relativePath = relative14(parentPath, childPath);
495248
495756
  if (relativePath === "" || relativePath === ".." || relativePath.startsWith(`..${sep8}`) || isAbsolute28(relativePath)) {
495249
495757
  throw new Error(`Imported skill file path escapes skill directory: ${child}`);
@@ -495261,7 +495769,7 @@ function validateImportedSkillFilePath(filePath) {
495261
495769
  }
495262
495770
  function resolveImportedSkillFilePath(skillDir, filePath) {
495263
495771
  const safeFilePath = validateImportedSkillFilePath(filePath);
495264
- const fullPath = resolve35(skillDir, safeFilePath);
495772
+ const fullPath = resolve36(skillDir, safeFilePath);
495265
495773
  assertPathInside(skillDir, fullPath);
495266
495774
  return fullPath;
495267
495775
  }
@@ -495295,7 +495803,7 @@ async function importAgentFromFile(options3) {
495295
495803
  if (!getBackend().capabilities.agentFileImportExport) {
495296
495804
  throw new Error("Agent file import is not supported by this backend yet");
495297
495805
  }
495298
- const resolvedPath = resolve35(options3.filePath);
495806
+ const resolvedPath = resolve36(options3.filePath);
495299
495807
  try {
495300
495808
  await access2(resolvedPath);
495301
495809
  } catch {
@@ -495333,14 +495841,14 @@ async function importAgentFromFile(options3) {
495333
495841
  }
495334
495842
  async function extractSkillsFromAf(afPath, destDir) {
495335
495843
  const extracted = [];
495336
- const content = await readFile29(afPath, "utf-8");
495844
+ const content = await readFile30(afPath, "utf-8");
495337
495845
  const afData = JSON.parse(content);
495338
495846
  if (!afData.skills || !Array.isArray(afData.skills)) {
495339
495847
  return [];
495340
495848
  }
495341
495849
  for (const skill2 of afData.skills) {
495342
495850
  const skillName = validateImportedSkillName(skill2.name);
495343
- const skillDir = resolve35(destDir, skillName);
495851
+ const skillDir = resolve36(destDir, skillName);
495344
495852
  await mkdir17(skillDir, { recursive: true });
495345
495853
  if (skill2.files) {
495346
495854
  await writeSkillFiles(skillDir, skill2.files);
@@ -495362,7 +495870,7 @@ async function writeSkillFiles(skillDir, files) {
495362
495870
  async function writeSkillFile(skillDir, filePath, content) {
495363
495871
  const fullPath = resolveImportedSkillFilePath(skillDir, filePath);
495364
495872
  await mkdir17(dirname34(fullPath), { recursive: true });
495365
- await writeFile19(fullPath, content, "utf-8");
495873
+ await writeFile20(fullPath, content, "utf-8");
495366
495874
  const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
495367
495875
  if (isScript) {
495368
495876
  try {
@@ -495415,7 +495923,7 @@ function parseRegistryHandle(handle2) {
495415
495923
  async function importAgentFromRegistry(options3) {
495416
495924
  const { tmpdir: tmpdir11 } = await import("node:os");
495417
495925
  const { join: join80 } = await import("node:path");
495418
- const { writeFile: writeFile20, unlink: unlink6 } = await import("node:fs/promises");
495926
+ const { writeFile: writeFile21, unlink: unlink6 } = await import("node:fs/promises");
495419
495927
  const { author, name } = parseRegistryHandle(options3.handle);
495420
495928
  const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER}/${AGENT_REGISTRY_REPO}/refs/heads/${AGENT_REGISTRY_BRANCH}/agents/@${author}/${name}/${name}.af`;
495421
495929
  const response = await fetch(rawUrl);
@@ -495427,7 +495935,7 @@ async function importAgentFromRegistry(options3) {
495427
495935
  }
495428
495936
  const afContent = await response.text();
495429
495937
  const tempPath = join80(tmpdir11(), `letta-import-${author}-${name}-${Date.now()}.af`);
495430
- await writeFile20(tempPath, afContent, "utf-8");
495938
+ await writeFile21(tempPath, afContent, "utf-8");
495431
495939
  try {
495432
495940
  const result = await importAgentFromFile({
495433
495941
  filePath: tempPath,
@@ -495840,10 +496348,10 @@ async function sendScopedApprovalMessages(params) {
495840
496348
  });
495841
496349
  }
495842
496350
  async function flushAndExit(code2) {
495843
- const flushWritable = (stream12) => new Promise((resolve36) => {
496351
+ const flushWritable = (stream12) => new Promise((resolve37) => {
495844
496352
  if (stream12.destroyed || stream12.writableEnded)
495845
- return resolve36();
495846
- stream12.write("", () => resolve36());
496353
+ return resolve37();
496354
+ stream12.write("", () => resolve37());
495847
496355
  });
495848
496356
  await closeClientMcpServers();
495849
496357
  await Promise.allSettled([
@@ -495853,12 +496361,12 @@ async function flushAndExit(code2) {
495853
496361
  process.exit(code2);
495854
496362
  }
495855
496363
  async function writeFinalHeadlessStdout(text2) {
495856
- await new Promise((resolve36) => {
496364
+ await new Promise((resolve37) => {
495857
496365
  if (process.stdout.destroyed || process.stdout.writableEnded) {
495858
- resolve36();
496366
+ resolve37();
495859
496367
  return;
495860
496368
  }
495861
- process.stdout.write(text2, () => resolve36());
496369
+ process.stdout.write(text2, () => resolve37());
495862
496370
  });
495863
496371
  }
495864
496372
  function pageItems5(page) {
@@ -495951,7 +496459,7 @@ async function waitForEnvironmentAssistantMessage(params) {
495951
496459
  return { text: text2, stopReason: observedStopReason };
495952
496460
  }
495953
496461
  }
495954
- await new Promise((resolve36) => setTimeout(resolve36, pollIntervalMs));
496462
+ await new Promise((resolve37) => setTimeout(resolve37, pollIntervalMs));
495955
496463
  }
495956
496464
  if (observedCompletion && lastText) {
495957
496465
  return { text: lastText, stopReason: observedStopReason };
@@ -496869,7 +497377,7 @@ ${loadedContents.join(`
496869
497377
  if (usesRemoteEnvironment) {
496870
497378
  const environmentSelector = String(explicitEnvironmentSelector);
496871
497379
  const useCloudSandbox = isCloudEnvironmentSelector(environmentSelector);
496872
- const environmentRouting = useCloudSandbox ? await resolveAgentSandboxConnectionId(agent2.id) : await resolveEnvironmentConnectionId(environmentSelector);
497380
+ const environmentRouting = useCloudSandbox ? await resolveAgentSandboxConnectionId(agent2.id, { conversationId }) : await resolveEnvironmentConnectionId(environmentSelector);
496873
497381
  const { connectionId, environment: environment2 } = environmentRouting;
496874
497382
  const responseEnvironment = buildEnvironmentResponseMetadata({
496875
497383
  source: useCloudSandbox ? "cloud-sandbox" : "explicit",
@@ -497178,7 +497686,7 @@ ${loadedContents.join(`
497178
497686
  } else {
497179
497687
  console.error(`Conversation is busy, waiting ${Math.round(retryDelayMs / 1000)}s and retrying...`);
497180
497688
  }
497181
- await new Promise((resolve36) => setTimeout(resolve36, retryDelayMs));
497689
+ await new Promise((resolve37) => setTimeout(resolve37, retryDelayMs));
497182
497690
  continue;
497183
497691
  }
497184
497692
  }
@@ -497227,7 +497735,7 @@ ${loadedContents.join(`
497227
497735
  const delaySeconds = Math.round(delayMs / 1000);
497228
497736
  console.error(`Transient API error before streaming (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
497229
497737
  }
497230
- await new Promise((resolve36) => setTimeout(resolve36, delayMs));
497738
+ await new Promise((resolve37) => setTimeout(resolve37, delayMs));
497231
497739
  conversationBusyRetries = 0;
497232
497740
  continue;
497233
497741
  }
@@ -497469,7 +497977,7 @@ ${loadedContents.join(`
497469
497977
  const delaySeconds = Math.round(delayMs / 1000);
497470
497978
  console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
497471
497979
  }
497472
- await new Promise((resolve36) => setTimeout(resolve36, delayMs));
497980
+ await new Promise((resolve37) => setTimeout(resolve37, delayMs));
497473
497981
  currentInput = refreshInputOtidsForNewRequest(currentInput);
497474
497982
  continue;
497475
497983
  }
@@ -497561,7 +498069,7 @@ ${loadedContents.join(`
497561
498069
  } else {
497562
498070
  console.error(`Empty LLM response, retrying (attempt ${attempt} of ${EMPTY_RESPONSE_MAX_RETRIES2})...`);
497563
498071
  }
497564
- await new Promise((resolve36) => setTimeout(resolve36, delayMs));
498072
+ await new Promise((resolve37) => setTimeout(resolve37, delayMs));
497565
498073
  currentInput = refreshInputOtidsForNewRequest(currentInput);
497566
498074
  continue;
497567
498075
  }
@@ -497589,7 +498097,7 @@ ${loadedContents.join(`
497589
498097
  const delaySeconds = Math.round(delayMs / 1000);
497590
498098
  console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
497591
498099
  }
497592
- await new Promise((resolve36) => setTimeout(resolve36, delayMs));
498100
+ await new Promise((resolve37) => setTimeout(resolve37, delayMs));
497593
498101
  currentInput = refreshInputOtidsForNewRequest(currentInput);
497594
498102
  continue;
497595
498103
  }
@@ -497619,7 +498127,7 @@ ${loadedContents.join(`
497619
498127
  const delaySeconds = Math.round(delayMs / 1000);
497620
498128
  console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
497621
498129
  }
497622
- await new Promise((resolve36) => setTimeout(resolve36, delayMs));
498130
+ await new Promise((resolve37) => setTimeout(resolve37, delayMs));
497623
498131
  currentInput = refreshInputOtidsForNewRequest(currentInput);
497624
498132
  continue;
497625
498133
  }
@@ -497628,7 +498136,7 @@ ${loadedContents.join(`
497628
498136
  markIncompleteToolsAsCancelled(buffers, true, "stream_error");
497629
498137
  const errorLines = toLines(buffers).filter((line) => line.kind === "error");
497630
498138
  const errorMessages2 = errorLines.map((line) => ("text" in line) ? line.text : "").filter(Boolean);
497631
- 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}`;
497632
498140
  let finalRun = null;
497633
498141
  if (lastRunId) {
497634
498142
  try {
@@ -497641,10 +498149,10 @@ ${loadedContents.join(`
497641
498149
  run_id: lastRunId
497642
498150
  }
497643
498151
  };
497644
- errorMessage2 = formatErrorDetails2(errorObject, agent2.id);
498152
+ errorMessage3 = formatErrorDetails2(errorObject, agent2.id);
497645
498153
  }
497646
498154
  } catch (_e) {
497647
- errorMessage2 = `${errorMessage2}
498155
+ errorMessage3 = `${errorMessage3}
497648
498156
  (Unable to fetch additional error details from server)`;
497649
498157
  }
497650
498158
  }
@@ -497653,11 +498161,11 @@ ${loadedContents.join(`
497653
498161
  await backend3.cancelRun(finalRun.agent_id || agent2.id, lastRunId);
497654
498162
  } catch {}
497655
498163
  }
497656
- trackHeadlessBoundaryError("headless_turn_failed", errorMessage2, "headless_turn_execution");
498164
+ trackHeadlessBoundaryError("headless_turn_failed", errorMessage3, "headless_turn_execution");
497657
498165
  if (outputFormat === "stream-json") {
497658
498166
  const errorMsg = {
497659
498167
  type: "error",
497660
- message: errorMessage2,
498168
+ message: errorMessage3,
497661
498169
  stop_reason: stopReason,
497662
498170
  run_id: lastRunId ?? undefined,
497663
498171
  session_id: sessionId,
@@ -497665,7 +498173,7 @@ ${loadedContents.join(`
497665
498173
  };
497666
498174
  await writeWireMessageAsync(errorMsg);
497667
498175
  } else {
497668
- console.error(`Error: ${errorMessage2}`);
498176
+ console.error(`Error: ${errorMessage3}`);
497669
498177
  }
497670
498178
  await exitHeadless(1, "headless_stop_reason_error");
497671
498179
  }
@@ -498014,9 +498522,9 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498014
498522
  const syntheticUserLine = serializeQueuedMessageAsUserLine(queuedMessage);
498015
498523
  maybeNotifyBlocked(syntheticUserLine);
498016
498524
  if (lineResolver) {
498017
- const resolve36 = lineResolver;
498525
+ const resolve37 = lineResolver;
498018
498526
  lineResolver = null;
498019
- resolve36(syntheticUserLine);
498527
+ resolve37(syntheticUserLine);
498020
498528
  return;
498021
498529
  }
498022
498530
  lineQueue.push(syntheticUserLine);
@@ -498036,9 +498544,9 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498036
498544
  if (action3 === "abort-active") {
498037
498545
  currentAbortController.abort();
498038
498546
  if (lineResolver) {
498039
- const resolve36 = lineResolver;
498547
+ const resolve37 = lineResolver;
498040
498548
  lineResolver = null;
498041
- resolve36(null);
498549
+ resolve37(null);
498042
498550
  }
498043
498551
  } else if (action3 === "latch") {
498044
498552
  pendingInterrupt = true;
@@ -498058,9 +498566,9 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498058
498566
  if (lineResolver) {
498059
498567
  if (parsedLine?.type === "user")
498060
498568
  turnStarting = true;
498061
- const resolve36 = lineResolver;
498569
+ const resolve37 = lineResolver;
498062
498570
  lineResolver = null;
498063
- resolve36(line);
498571
+ resolve37(line);
498064
498572
  } else {
498065
498573
  lineQueue.push(line);
498066
498574
  }
@@ -498069,17 +498577,17 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498069
498577
  setMessageQueueAdder(null);
498070
498578
  msgQueueRuntime.clear("shutdown");
498071
498579
  if (lineResolver) {
498072
- const resolve36 = lineResolver;
498580
+ const resolve37 = lineResolver;
498073
498581
  lineResolver = null;
498074
- resolve36(null);
498582
+ resolve37(null);
498075
498583
  }
498076
498584
  });
498077
498585
  async function getNextLine() {
498078
498586
  if (lineQueue.length > 0) {
498079
498587
  return lineQueue.shift() ?? null;
498080
498588
  }
498081
- return new Promise((resolve36) => {
498082
- lineResolver = resolve36;
498589
+ return new Promise((resolve37) => {
498590
+ lineResolver = resolve37;
498083
498591
  });
498084
498592
  }
498085
498593
  async function requestPermission(toolCallId, toolName, toolInput) {
@@ -498141,9 +498649,9 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498141
498649
  }
498142
498650
  return result;
498143
498651
  }
498144
- async function recoverPendingApprovalsFromControlRequest(request) {
498145
- const targetAgentId = request.agent_id ?? agent2.id;
498146
- 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;
498147
498655
  if (targetAgentId !== agent2.id) {
498148
498656
  throw new Error(`recover_pending_approvals agent mismatch: ${targetAgentId} != ${agent2.id}`);
498149
498657
  }
@@ -498600,7 +499108,7 @@ async function runBidirectionalMode(agent2, conversationId, _outputFormat, inclu
498600
499108
  uuid: `retry-bidir-${randomUUID34()}`
498601
499109
  };
498602
499110
  writeWireMessage(retryMsg);
498603
- await new Promise((resolve36) => setTimeout(resolve36, delayMs));
499111
+ await new Promise((resolve37) => setTimeout(resolve37, delayMs));
498604
499112
  continue;
498605
499113
  }
498606
499114
  throw preStreamError;
@@ -499311,7 +499819,7 @@ var BYTES_PER_TOKEN = 4;
499311
499819
 
499312
499820
  // src/cli/helpers/window-title-config.ts
499313
499821
  import { homedir as homedir44 } from "node:os";
499314
- import { basename as basename31, resolve as resolve36 } from "node:path";
499822
+ import { basename as basename32, resolve as resolve37 } from "node:path";
499315
499823
  function isWindowTitleField(value) {
499316
499824
  return WINDOW_TITLE_FIELDS.includes(value);
499317
499825
  }
@@ -499469,8 +499977,8 @@ function terminalTitleProjectName(data) {
499469
499977
  const directory = titleDirectory(data);
499470
499978
  if (!directory)
499471
499979
  return null;
499472
- const resolved = resolve36(directory);
499473
- const name = basename31(resolved) || formatDirectoryDisplay(resolved) || resolved;
499980
+ const resolved = resolve37(directory);
499981
+ const name = basename32(resolved) || formatDirectoryDisplay(resolved) || resolved;
499474
499982
  return truncateTerminalTitlePart(name, 24);
499475
499983
  }
499476
499984
  function titleDirectory(data) {
@@ -499479,7 +499987,7 @@ function titleDirectory(data) {
499479
499987
  function formatDirectoryDisplay(directory) {
499480
499988
  if (!directory)
499481
499989
  return null;
499482
- const resolved = resolve36(directory);
499990
+ const resolved = resolve37(directory);
499483
499991
  const home = homedir44();
499484
499992
  if (resolved === home)
499485
499993
  return "~";
@@ -500193,7 +500701,7 @@ var init_queued_message_parts = __esm(() => {
500193
500701
  // src/cli/helpers/reflection-arena-hf-upload.ts
500194
500702
  import { execFile as execFileCb5 } from "node:child_process";
500195
500703
  import { existsSync as existsSync63 } from "node:fs";
500196
- 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";
500197
500705
  import { homedir as homedir45 } from "node:os";
500198
500706
  import { join as join81 } from "node:path";
500199
500707
  import { promisify as promisify15 } from "node:util";
@@ -500232,7 +500740,7 @@ async function runGit6(cwd2, args, env5) {
500232
500740
  }
500233
500741
  async function writeGitAskpass(repoRoot) {
500234
500742
  const askpassPath = join81(repoRoot, "hf-askpass.sh");
500235
- await writeFile20(askpassPath, [
500743
+ await writeFile21(askpassPath, [
500236
500744
  "#!/bin/sh",
500237
500745
  'case "$1" in',
500238
500746
  " *Username*) printf '%s\\n' 'hf_user' ;;",
@@ -500317,7 +500825,7 @@ var init_reflection_arena_hf_upload = __esm(() => {
500317
500825
  // src/cli/helpers/reflection-arena.ts
500318
500826
  import { execFile as execFileCb6 } from "node:child_process";
500319
500827
  import { randomInt as randomInt2, randomUUID as randomUUID35 } from "node:crypto";
500320
- 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";
500321
500829
  import { homedir as homedir46 } from "node:os";
500322
500830
  import { join as join82 } from "node:path";
500323
500831
  import { promisify as promisify16 } from "node:util";
@@ -500381,11 +500889,11 @@ function getReflectionArenaRunPath(runId) {
500381
500889
  }
500382
500890
  async function saveReflectionArenaRun(run) {
500383
500891
  await mkdir19(getReflectionArenaRunsDir(), { recursive: true });
500384
- await writeFile21(getReflectionArenaRunPath(run.runId), `${JSON.stringify(run, null, 2)}
500892
+ await writeFile22(getReflectionArenaRunPath(run.runId), `${JSON.stringify(run, null, 2)}
500385
500893
  `, "utf-8");
500386
500894
  }
500387
500895
  async function loadReflectionArenaRun(runId) {
500388
- const raw2 = await readFile30(getReflectionArenaRunPath(runId), "utf-8");
500896
+ const raw2 = await readFile31(getReflectionArenaRunPath(runId), "utf-8");
500389
500897
  return JSON.parse(raw2);
500390
500898
  }
500391
500899
  async function updateReflectionArenaRun(runId, update2) {
@@ -500577,7 +501085,7 @@ async function appendChoiceRecord(run) {
500577
501085
  }
500578
501086
  async function readTranscriptPayloadForTelemetry(payloadPath) {
500579
501087
  try {
500580
- const transcript = await readFile30(payloadPath, "utf-8");
501088
+ const transcript = await readFile31(payloadPath, "utf-8");
500581
501089
  return {
500582
501090
  transcriptPayload: transcript.slice(0, REFLECTION_ARENA_TELEMETRY_TRANSCRIPT_MAX_CHARS),
500583
501091
  transcriptPayloadChars: transcript.length,
@@ -500843,6 +501351,7 @@ async function finalizeReflectionArenaChoice(options3) {
500843
501351
  }
500844
501352
  const discarded = [];
500845
501353
  let integration;
501354
+ let completionSuccess = false;
500846
501355
  let memoryBaseCommit = null;
500847
501356
  let memoryCandidateCommit = null;
500848
501357
  if (options3.choice !== "tie") {
@@ -500869,6 +501378,7 @@ async function finalizeReflectionArenaChoice(options3) {
500869
501378
  logRecompileFailure: (message) => debugWarn("memory", message)
500870
501379
  });
500871
501380
  integration = finalized.integration;
501381
+ completionSuccess = finalized.completionSuccess;
500872
501382
  }
500873
501383
  for (const candidate of run.candidates) {
500874
501384
  if (options3.choice !== "tie" && candidate.label === options3.choice) {
@@ -500880,7 +501390,7 @@ async function finalizeReflectionArenaChoice(options3) {
500880
501390
  knownNoChanges: candidateIsConfirmedNoOp(candidate)
500881
501391
  });
500882
501392
  }
500883
- 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);
500884
501394
  const completedRun = {
500885
501395
  ...run,
500886
501396
  choice: {
@@ -500921,6 +501431,7 @@ var init_reflection_arena = __esm(() => {
500921
501431
  init_memory_worktree();
500922
501432
  init_app_urls();
500923
501433
  init_reflection_arena_hf_upload();
501434
+ init_reflection_completion();
500924
501435
  init_reflection_launcher();
500925
501436
  init_reflection_transcript();
500926
501437
  init_telemetry();
@@ -501224,8 +501735,8 @@ async function pushToMemoryRepositoryWithTimeout(agentId) {
501224
501735
  try {
501225
501736
  return await Promise.race([
501226
501737
  pushToMemoryRepository(agentId),
501227
- new Promise((resolve37) => {
501228
- timeout = setTimeout(() => resolve37("timeout"), INITIAL_PUSH_TIMEOUT_MS);
501738
+ new Promise((resolve38) => {
501739
+ timeout = setTimeout(() => resolve38("timeout"), INITIAL_PUSH_TIMEOUT_MS);
501229
501740
  })
501230
501741
  ]);
501231
501742
  } finally {
@@ -507539,11 +508050,11 @@ var init_HelpDialog = __esm(async () => {
507539
508050
 
507540
508051
  // src/hooks/writer.ts
507541
508052
  import { homedir as homedir49 } from "node:os";
507542
- import { resolve as resolve37 } from "node:path";
508053
+ import { resolve as resolve38 } from "node:path";
507543
508054
  function isProjectSettingsPathCollidingWithGlobal2(workingDirectory) {
507544
508055
  const home = process.env.HOME || homedir49();
507545
- const globalSettingsPath = resolve37(home, ".letta", "settings.json");
507546
- const projectSettingsPath = resolve37(workingDirectory, ".letta", "settings.json");
508056
+ const globalSettingsPath = resolve38(home, ".letta", "settings.json");
508057
+ const projectSettingsPath = resolve38(workingDirectory, ".letta", "settings.json");
507547
508058
  return globalSettingsPath === projectSettingsPath;
507548
508059
  }
507549
508060
  function loadHooksFromLocation(location, workingDirectory = process.cwd()) {
@@ -513837,7 +514348,7 @@ var init_InstallGithubAppFlow = __esm(async () => {
513837
514348
  const solidLine = SOLID_LINE11.repeat(Math.max(terminalWidth, 10));
513838
514349
  const [step, setStep] = import_react84.useState("checking");
513839
514350
  const [status, setStatus] = import_react84.useState("Checking GitHub CLI prerequisites...");
513840
- const [errorMessage2, setErrorMessage] = import_react84.useState("");
514351
+ const [errorMessage3, setErrorMessage] = import_react84.useState("");
513841
514352
  const [currentRepo, setCurrentRepo] = import_react84.useState(null);
513842
514353
  const [repoChoiceIndex, setRepoChoiceIndex] = import_react84.useState(0);
513843
514354
  const [repoInput, setRepoInput] = import_react84.useState("");
@@ -514405,14 +514916,14 @@ var init_InstallGithubAppFlow = __esm(async () => {
514405
514916
  color: "red",
514406
514917
  children: [
514407
514918
  "Error: ",
514408
- errorMessage2.split(`
514919
+ errorMessage3.split(`
514409
514920
  `)[0] || "Unknown error"
514410
514921
  ]
514411
514922
  }, undefined, true, undefined, this),
514412
514923
  /* @__PURE__ */ jsx_dev_runtime62.jsxDEV(Box_default, {
514413
514924
  height: 1
514414
514925
  }, undefined, false, undefined, this),
514415
- errorMessage2.split(`
514926
+ errorMessage3.split(`
514416
514927
  `).slice(1).filter((line) => line.trim().length > 0).map((line, idx) => /* @__PURE__ */ jsx_dev_runtime62.jsxDEV(Text2, {
514417
514928
  dimColor: true,
514418
514929
  children: line
@@ -518822,14 +519333,14 @@ function MessageSearch({
518822
519333
  resultsCache.current.set(cacheKey, emptyResults);
518823
519334
  return emptyResults;
518824
519335
  }
518825
- const request = fetchSearchResults(query2, mode, range3).then((searchResults) => {
519336
+ const request2 = fetchSearchResults(query2, mode, range3).then((searchResults) => {
518826
519337
  resultsCache.current.set(cacheKey, searchResults);
518827
519338
  return searchResults;
518828
519339
  }).finally(() => {
518829
519340
  pendingResultsCache.current.delete(cacheKey);
518830
519341
  });
518831
- pendingResultsCache.current.set(cacheKey, request);
518832
- return request;
519342
+ pendingResultsCache.current.set(cacheKey, request2);
519343
+ return request2;
518833
519344
  }, [agentId, conversationId, fetchSearchResults, getCacheKey]);
518834
519345
  const prefetchSearchResults = import_react89.useCallback((query2, mode, range3) => {
518835
519346
  const { prefetch } = buildSearchTargetPlan(mode, range3, {
@@ -520226,7 +520737,7 @@ var init_PersonalitySelector = __esm(async () => {
520226
520737
  });
520227
520738
 
520228
520739
  // src/utils/aws-credentials.ts
520229
- import { readFile as readFile31 } from "node:fs/promises";
520740
+ import { readFile as readFile32 } from "node:fs/promises";
520230
520741
  import { homedir as homedir51 } from "node:os";
520231
520742
  import { join as join88 } from "node:path";
520232
520743
  async function parseAwsCredentials() {
@@ -520234,11 +520745,11 @@ async function parseAwsCredentials() {
520234
520745
  const configPath = join88(homedir51(), ".aws", "config");
520235
520746
  const profiles = new Map;
520236
520747
  try {
520237
- const content = await readFile31(credentialsPath, "utf-8");
520748
+ const content = await readFile32(credentialsPath, "utf-8");
520238
520749
  parseIniFile(content, profiles, false);
520239
520750
  } catch {}
520240
520751
  try {
520241
- const content = await readFile31(configPath, "utf-8");
520752
+ const content = await readFile32(configPath, "utf-8");
520242
520753
  parseIniFile(content, profiles, true);
520243
520754
  } catch {}
520244
520755
  return Array.from(profiles.values());
@@ -524400,7 +524911,7 @@ var init_ToolCallMessageRich = __esm(async () => {
524400
524911
  let shellSemanticKind = null;
524401
524912
  let hasShellDescription = false;
524402
524913
  if (!isQuestionTool(rawName)) {
524403
- const parseArgs18 = () => {
524914
+ const parseArgs19 = () => {
524404
524915
  if (!argsText.trim()) {
524405
524916
  return { formatted: null, parseable: true };
524406
524917
  }
@@ -524414,7 +524925,7 @@ var init_ToolCallMessageRich = __esm(async () => {
524414
524925
  return { formatted: null, parseable: false };
524415
524926
  }
524416
524927
  };
524417
- const { formatted, parseable } = parseArgs18();
524928
+ const { formatted, parseable } = parseArgs19();
524418
524929
  const argsComplete = parseable || line.phase === "running" || line.phase === "finished" || !isStreaming;
524419
524930
  if (!argsComplete) {
524420
524931
  args = "(…)";
@@ -526630,7 +527141,7 @@ function updateCommandResult(buffersRef, refreshDerived, cmdId, input, output, s
526630
527141
  buffersRef.current.byId.set(cmdId, line);
526631
527142
  refreshDerived();
526632
527143
  }
526633
- function parseArgs18(msg) {
527144
+ function parseArgs19(msg) {
526634
527145
  return msg.trim().split(/\s+/).filter(Boolean);
526635
527146
  }
526636
527147
  function formatConnectUsage() {
@@ -526986,7 +527497,7 @@ ${formatBedrockUsage2()}`, false);
526986
527497
  }
526987
527498
  }
526988
527499
  async function handleConnect(ctx, msg) {
526989
- const parts = parseArgs18(msg);
527500
+ const parts = parseArgs19(msg);
526990
527501
  const providerToken = parts[1];
526991
527502
  if (!providerToken) {
526992
527503
  addCommandResult(ctx.buffersRef, ctx.refreshDerived, msg, formatConnectUsage(), false);
@@ -536828,13 +537339,13 @@ var init_cleanLastNewline = () => {};
536828
537339
  function processLine(node, line, state) {
536829
537340
  const lineInfo = typeof state.lineInfo === "function" ? state.lineInfo(line) : state.lineInfo[line - 1];
536830
537341
  if (lineInfo == null) {
536831
- const errorMessage2 = `processLine: line ${line}, contains no state.lineInfo`;
536832
- console.error(errorMessage2, {
537342
+ const errorMessage3 = `processLine: line ${line}, contains no state.lineInfo`;
537343
+ console.error(errorMessage3, {
536833
537344
  node,
536834
537345
  line,
536835
537346
  state
536836
537347
  });
536837
- throw new Error(errorMessage2);
537348
+ throw new Error(errorMessage3);
536838
537349
  }
536839
537350
  node.tagName = "div";
536840
537351
  node.properties["data-line"] = lineInfo.lineNumber;
@@ -540306,9 +540817,9 @@ var instanceId = -1, DiffHunksRenderer = class {
540306
540817
  let deletionLineContent = deletionLine != null ? deletionLines[deletionLine.lineIndex] : undefined;
540307
540818
  let additionLineContent = additionLine != null ? additionLines[additionLine.lineIndex] : undefined;
540308
540819
  if (deletionLineContent == null && additionLineContent == null) {
540309
- const errorMessage2 = "DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong";
540310
- console.error(errorMessage2, { file: fileDiff.name });
540311
- 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);
540312
540823
  }
540313
540824
  const lineType = type3 === "change" ? additionLine != null ? "change-addition" : "change-deletion" : type3;
540314
540825
  const lineDecoration = this.getUnifiedLineDecoration({
@@ -540350,9 +540861,9 @@ var instanceId = -1, DiffHunksRenderer = class {
540350
540861
  lineIndex: additionLine?.lineIndex
540351
540862
  });
540352
540863
  if (deletionLineContent == null && additionLineContent == null) {
540353
- const errorMessage2 = "DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong";
540354
- console.error(errorMessage2, { file: fileDiff.name });
540355
- 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);
540356
540867
  }
540357
540868
  const missingSide = (() => {
540358
540869
  if (type3 === "change") {
@@ -541345,7 +541856,7 @@ __export(exports_generate_diff_viewer, {
541345
541856
  import { execFile as execFileCb8 } from "node:child_process";
541346
541857
  import { chmodSync as chmodSync8, existsSync as existsSync68, mkdirSync as mkdirSync48, writeFileSync as writeFileSync38 } from "node:fs";
541347
541858
  import { homedir as homedir52 } from "node:os";
541348
- 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";
541349
541860
  import { promisify as promisify18 } from "node:util";
541350
541861
  async function runGit8(cwd2, args) {
541351
541862
  try {
@@ -541543,7 +542054,7 @@ function escapeHtml3(value) {
541543
542054
  function resolveTargetPath(targetPath) {
541544
542055
  if (!targetPath?.trim())
541545
542056
  return process.cwd();
541546
- return isAbsolute29(targetPath) ? targetPath : resolve38(process.cwd(), targetPath);
542057
+ return isAbsolute29(targetPath) ? targetPath : resolve39(process.cwd(), targetPath);
541547
542058
  }
541548
542059
  function shouldSkipOpen() {
541549
542060
  return Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
@@ -544827,7 +545338,7 @@ var init_system_reminders = __esm(() => {
544827
545338
  // src/cli/app/use-conversation-loop.ts
544828
545339
  import { randomUUID as randomUUID38 } from "node:crypto";
544829
545340
  function sleep10(ms) {
544830
- return new Promise((resolve39) => setTimeout(resolve39, ms));
545341
+ return new Promise((resolve40) => setTimeout(resolve40, ms));
544831
545342
  }
544832
545343
  function makeExecutionPhaseHook(setExecutionPhase) {
544833
545344
  return ({ chunk }) => {
@@ -545278,7 +545789,7 @@ function useConversationLoop(ctx) {
545278
545789
  cancelled = true;
545279
545790
  break;
545280
545791
  }
545281
- await new Promise((resolve39) => setTimeout(resolve39, 100));
545792
+ await new Promise((resolve40) => setTimeout(resolve40, 100));
545282
545793
  }
545283
545794
  buffersRef.current.byId.delete(statusId);
545284
545795
  buffersRef.current.order = buffersRef.current.order.filter((id2) => id2 !== statusId);
@@ -545342,7 +545853,7 @@ function useConversationLoop(ctx) {
545342
545853
  cancelled = true;
545343
545854
  break;
545344
545855
  }
545345
- await new Promise((resolve39) => setTimeout(resolve39, 100));
545856
+ await new Promise((resolve40) => setTimeout(resolve40, 100));
545346
545857
  }
545347
545858
  if (retryStatusId) {
545348
545859
  buffersRef.current.byId.delete(retryStatusId);
@@ -546136,7 +546647,7 @@ ${feedback}
546136
546647
  });
546137
546648
  buffersRef.current.order.push(statusId);
546138
546649
  refreshDerived();
546139
- await new Promise((resolve39) => setTimeout(resolve39, delayMs));
546650
+ await new Promise((resolve40) => setTimeout(resolve40, delayMs));
546140
546651
  buffersRef.current.byId.delete(statusId);
546141
546652
  buffersRef.current.order = buffersRef.current.order.filter((id2) => id2 !== statusId);
546142
546653
  refreshDerived();
@@ -546196,7 +546707,7 @@ ${feedback}
546196
546707
  cancelled = true;
546197
546708
  break;
546198
546709
  }
546199
- await new Promise((resolve39) => setTimeout(resolve39, 100));
546710
+ await new Promise((resolve40) => setTimeout(resolve40, 100));
546200
546711
  }
546201
546712
  if (retryStatusId) {
546202
546713
  buffersRef.current.byId.delete(retryStatusId);
@@ -547932,7 +548443,7 @@ The deployment target for this project is CITATION-DOGFOOD-OK.
547932
548443
 
547933
548444
  // src/mods/learning-harness.ts
547934
548445
  import { spawn as spawn13 } from "node:child_process";
547935
- 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";
547936
548447
  import path47 from "node:path";
547937
548448
  function slugify2(value) {
547938
548449
  const slug = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
@@ -548180,14 +548691,14 @@ async function existingPath(filePath) {
548180
548691
  return await fileExists(filePath) ? filePath : undefined;
548181
548692
  }
548182
548693
  async function writeJsonArtifact(filePath, value) {
548183
- await writeFile22(filePath, `${JSON.stringify(value, null, 2)}
548694
+ await writeFile23(filePath, `${JSON.stringify(value, null, 2)}
548184
548695
  `, "utf8");
548185
548696
  }
548186
548697
  async function writeCommandArtifacts(prefix, command, args, result) {
548187
- await writeFile22(`${prefix}.command.txt`, `${renderCommand(command, args)}
548698
+ await writeFile23(`${prefix}.command.txt`, `${renderCommand(command, args)}
548188
548699
  `, "utf8");
548189
- await writeFile22(`${prefix}.stdout`, result.stdout, "utf8");
548190
- await writeFile22(`${prefix}.stderr`, result.stderr, "utf8");
548700
+ await writeFile23(`${prefix}.stdout`, result.stdout, "utf8");
548701
+ await writeFile23(`${prefix}.stderr`, result.stderr, "utf8");
548191
548702
  await writeJsonArtifact(`${prefix}.result.json`, result);
548192
548703
  }
548193
548704
  async function prepareMemoryFiles(memoryDir, memoryFiles) {
@@ -548195,7 +548706,7 @@ async function prepareMemoryFiles(memoryDir, memoryFiles) {
548195
548706
  for (const [relativePath, content] of Object.entries(memoryFiles ?? {})) {
548196
548707
  const filePath = safeJoin(memoryDir, relativePath);
548197
548708
  await mkdir20(path47.dirname(filePath), { recursive: true });
548198
- await writeFile22(filePath, content, "utf8");
548709
+ await writeFile23(filePath, content, "utf8");
548199
548710
  }
548200
548711
  }
548201
548712
  function renderEvaluationPrompt(prompt, memoryDir) {
@@ -548858,7 +549369,7 @@ function renderProposerGuide(params) {
548858
549369
  `;
548859
549370
  }
548860
549371
  async function writeHistoryArtifacts(params) {
548861
- await writeFile22(params.historyPath, renderHistoryIndex({
549372
+ await writeFile23(params.historyPath, renderHistoryIndex({
548862
549373
  attempts: params.attempts,
548863
549374
  historyManifestPath: params.historyManifestPath,
548864
549375
  proposerGuidePath: params.proposerGuidePath,
@@ -548866,11 +549377,11 @@ async function writeHistoryArtifacts(params) {
548866
549377
  spec: params.spec
548867
549378
  }), "utf8");
548868
549379
  await writeJsonArtifact(params.historyManifestPath, buildHistoryManifest(params));
548869
- await writeFile22(params.proposerGuidePath, renderProposerGuide(params), "utf8");
549380
+ await writeFile23(params.proposerGuidePath, renderProposerGuide(params), "utf8");
548870
549381
  }
548871
549382
  async function defaultCommandRunner(command, args, options3) {
548872
549383
  const startedAt = Date.now();
548873
- return new Promise((resolve39) => {
549384
+ return new Promise((resolve40) => {
548874
549385
  const child = spawn13(command, args, {
548875
549386
  cwd: options3.cwd,
548876
549387
  env: options3.env,
@@ -548897,7 +549408,7 @@ async function defaultCommandRunner(command, args, options3) {
548897
549408
  });
548898
549409
  child.on("close", (exitCode) => {
548899
549410
  clearTimeout(timeout);
548900
- resolve39({
549411
+ resolve40({
548901
549412
  args,
548902
549413
  command,
548903
549414
  cwd: options3.cwd,
@@ -548957,7 +549468,7 @@ function createScenarioSuiteEvaluator(params) {
548957
549468
  outputFormat
548958
549469
  })
548959
549470
  ];
548960
- 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");
548961
549472
  const scenarioEvalResult = await context3.runner(context3.cliCommand, evalArgs, {
548962
549473
  cwd: context3.repoRoot,
548963
549474
  env: {
@@ -549149,7 +549660,7 @@ async function runModLearningCandidate(params) {
549149
549660
  outputFormat: "json"
549150
549661
  })
549151
549662
  ];
549152
- await writeFile22(path47.join(runDir, "generation-prompt.md"), generationPrompt, "utf8");
549663
+ await writeFile23(path47.join(runDir, "generation-prompt.md"), generationPrompt, "utf8");
549153
549664
  generationResult = await params.runner(params.cliCommand, generationArgs, {
549154
549665
  cwd: repoRoot,
549155
549666
  env: {
@@ -549228,7 +549739,7 @@ async function runModLearningCandidate(params) {
549228
549739
  spec: options3.spec
549229
549740
  };
549230
549741
  await writeJsonArtifact(path47.join(runDir, "report.json"), report);
549231
- await writeFile22(reportPath, renderMarkdownReport(report), "utf8");
549742
+ await writeFile23(reportPath, renderMarkdownReport(report), "utf8");
549232
549743
  await writeCandidateManifest(report);
549233
549744
  emitProgress("done", params.candidateCount > 1 ? `Optimization iteration ${params.candidateIndex}/${params.candidateCount} complete` : "mod optimization complete", {
549234
549745
  attempts: [...params.previousAttempts, summarizeAttempt(report)],
@@ -549406,7 +549917,7 @@ async function runModLearning(options3) {
549406
549917
  spec: normalizedOptions.spec
549407
549918
  });
549408
549919
  await writeJsonArtifact(path47.join(runDir, "report.json"), report);
549409
- await writeFile22(reportPath, renderMarkdownReport(report), "utf8");
549920
+ await writeFile23(reportPath, renderMarkdownReport(report), "utf8");
549410
549921
  normalizedOptions.onProgress?.({
549411
549922
  candidateCount,
549412
549923
  candidateIndex: selectedCandidateIndex,
@@ -549424,7 +549935,7 @@ async function runModLearning(options3) {
549424
549935
  return report;
549425
549936
  }
549426
549937
  async function readModLearningEnv(envPath) {
549427
- return JSON.parse(await readFile32(envPath, "utf8"));
549938
+ return JSON.parse(await readFile33(envPath, "utf8"));
549428
549939
  }
549429
549940
  var init_learning_harness = __esm(async () => {
549430
549941
  await init_mod_engine();
@@ -549992,7 +550503,7 @@ var init_mods2 = __esm(async () => {
549992
550503
  });
549993
550504
 
549994
550505
  // src/cli/helpers/chdir-command.ts
549995
- import { realpath as realpath5, stat as stat17 } from "node:fs/promises";
550506
+ import { realpath as realpath5, stat as stat18 } from "node:fs/promises";
549996
550507
  import { homedir as homedir54 } from "node:os";
549997
550508
  import path49 from "node:path";
549998
550509
  function parseChdirCommand(input) {
@@ -550031,7 +550542,7 @@ async function resolveChdirTarget(pathArg, currentWorkingDirectory) {
550031
550542
  const expanded = expandHome(pathArg);
550032
550543
  const resolved = path49.isAbsolute(expanded) ? expanded : path49.resolve(currentWorkingDirectory, expanded);
550033
550544
  const normalized = await realpath5(resolved);
550034
- const stats = await stat17(normalized);
550545
+ const stats = await stat18(normalized);
550035
550546
  if (!stats.isDirectory()) {
550036
550547
  throw new Error(`Not a directory: ${normalized}`);
550037
550548
  }
@@ -551675,7 +552186,7 @@ __export(exports_worktree_diff_list, {
551675
552186
  listWorktreeDiffOptions: () => listWorktreeDiffOptions
551676
552187
  });
551677
552188
  import { execFile as execFileCb9 } from "node:child_process";
551678
- import { basename as basename32 } from "node:path";
552189
+ import { basename as basename33 } from "node:path";
551679
552190
  import { promisify as promisify19 } from "node:util";
551680
552191
  async function runGit9(cwd2, args) {
551681
552192
  try {
@@ -551724,7 +552235,7 @@ function parseWorktreeList(output, currentPath) {
551724
552235
  if (current?.path) {
551725
552236
  worktrees.push({
551726
552237
  path: current.path,
551727
- name: basename32(current.path),
552238
+ name: basename33(current.path),
551728
552239
  branch: current.branch ?? "detached",
551729
552240
  head: current.head ?? "",
551730
552241
  isCurrent: current.path === currentPath,
@@ -551750,7 +552261,7 @@ function parseWorktreeList(output, currentPath) {
551750
552261
  if (current?.path) {
551751
552262
  worktrees.push({
551752
552263
  path: current.path,
551753
- name: basename32(current.path),
552264
+ name: basename33(current.path),
551754
552265
  branch: current.branch ?? "detached",
551755
552266
  head: current.head ?? "",
551756
552267
  isCurrent: current.path === currentPath,
@@ -551819,15 +552330,15 @@ var exports_export = {};
551819
552330
  __export(exports_export, {
551820
552331
  packageSkills: () => packageSkills
551821
552332
  });
551822
- import { readdir as readdir17, readFile as readFile33 } from "node:fs/promises";
551823
- 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";
551824
552335
  async function packageSkills(agentId, skillsDir) {
551825
552336
  const skills = [];
551826
552337
  const skillNames = new Set;
551827
552338
  const dirsToCheck = skillsDir ? [skillsDir] : [
551828
552339
  agentId && getAgentSkillsDir(agentId),
551829
- resolve39(process.cwd(), ".skills"),
551830
- resolve39(process.env.HOME || "~", ".letta", "skills")
552340
+ resolve40(process.cwd(), ".skills"),
552341
+ resolve40(process.env.HOME || "~", ".letta", "skills")
551831
552342
  ].filter((dir) => Boolean(dir));
551832
552343
  for (const baseDir of dirsToCheck) {
551833
552344
  try {
@@ -551837,10 +552348,10 @@ async function packageSkills(agentId, skillsDir) {
551837
552348
  continue;
551838
552349
  if (skillNames.has(entry.name))
551839
552350
  continue;
551840
- const skillDir = resolve39(baseDir, entry.name);
551841
- const skillMdPath = resolve39(skillDir, "SKILL.md");
552351
+ const skillDir = resolve40(baseDir, entry.name);
552352
+ const skillMdPath = resolve40(skillDir, "SKILL.md");
551842
552353
  try {
551843
- await readFile33(skillMdPath, "utf-8");
552354
+ await readFile34(skillMdPath, "utf-8");
551844
552355
  } catch {
551845
552356
  console.warn(`Skipping invalid skill ${entry.name}: missing SKILL.md`);
551846
552357
  continue;
@@ -551868,11 +552379,11 @@ async function readSkillFiles(skillDir) {
551868
552379
  async function walk(dir) {
551869
552380
  const entries = await readdir17(dir, { withFileTypes: true });
551870
552381
  for (const entry of entries) {
551871
- const fullPath = resolve39(dir, entry.name);
552382
+ const fullPath = resolve40(dir, entry.name);
551872
552383
  if (entry.isDirectory()) {
551873
552384
  await walk(fullPath);
551874
552385
  } else {
551875
- const content = await readFile33(fullPath, "utf-8");
552386
+ const content = await readFile34(fullPath, "utf-8");
551876
552387
  const relativePath = relative17(skillDir, fullPath).replace(/\\/g, "/");
551877
552388
  files[relativePath] = content;
551878
552389
  }
@@ -552526,7 +553037,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
552526
553037
  agentId,
552527
553038
  allowDisabledModelInvocation: true
552528
553039
  });
552529
- 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.";
552530
553041
  cmd.finish("Running mod env generation...", true);
552531
553042
  await processConversationWithQueuedApprovals([
552532
553043
  {
@@ -552535,7 +553046,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
552535
553046
  content: buildTextParts(`${wrapSkillContent2("generating-mod-envs", skillContent)}
552536
553047
 
552537
553048
  ${SYSTEM_REMINDER_OPEN}
552538
- ${request}
553049
+ ${request2}
552539
553050
  ${SYSTEM_REMINDER_CLOSE}`),
552540
553051
  otid: randomUUID40()
552541
553052
  }
@@ -552795,7 +553306,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
552795
553306
  agentId,
552796
553307
  allowDisabledModelInvocation: true
552797
553308
  });
552798
- 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.";
552799
553310
  cmd.finish("Running statusline setup...", true);
552800
553311
  await processConversationWithQueuedApprovals([
552801
553312
  {
@@ -552804,7 +553315,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
552804
553315
  content: buildTextParts(`${wrapSkillContent2("customizing-statusline", skillContent)}
552805
553316
 
552806
553317
  ${SYSTEM_REMINDER_OPEN}
552807
- ${request}
553318
+ ${request2}
552808
553319
  ${SYSTEM_REMINDER_CLOSE}`),
552809
553320
  otid: randomUUID40()
552810
553321
  }
@@ -553963,7 +554474,7 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
553963
554474
  recompileQueuedByConversation: queuedSystemPromptRecompileByConversationRef.current,
553964
554475
  logRecompileFailure: (message2) => debugWarn("memory", message2)
553965
554476
  });
553966
- await finalizeMultiReflectionPayload(agentId, autoReflectionPayload.manifest, completionSuccess);
554477
+ await finalizeMultiReflectionCompletion(agentId, autoReflectionPayload.manifest, completionSuccess);
553967
554478
  appendTaskNotificationEvents([completionMessage]);
553968
554479
  } finally {
553969
554480
  releaseReflectionReservation();
@@ -554058,7 +554569,7 @@ Resumed reflection arena choice prompt for run ${run2.runId}.`, true);
554058
554569
  recompileQueuedByConversation: queuedSystemPromptRecompileByConversationRef.current,
554059
554570
  logRecompileFailure: (message2) => debugWarn("memory", message2)
554060
554571
  });
554061
- await finalizeMultiReflectionPayload(agentId, reflectionPayload.manifest, completionSuccess);
554572
+ await finalizeMultiReflectionCompletion(agentId, reflectionPayload.manifest, completionSuccess);
554062
554573
  appendTaskNotificationEvents([completionMessage]);
554063
554574
  } finally {
554064
554575
  releaseReflectionReservation();
@@ -554508,6 +555019,7 @@ var init_use_submit_handler = __esm(async () => {
554508
555019
  init_paste_registry();
554509
555020
  init_reasoning_tab_toggle();
554510
555021
  init_reflection_arena();
555022
+ init_reflection_completion();
554511
555023
  init_reflection_launcher();
554512
555024
  init_reflection_transcript();
554513
555025
  init_skill_name_frontmatter_repair();
@@ -558112,13 +558624,13 @@ USAGE
558112
558624
  # maintenance
558113
558625
  letta update Manually check for updates and install if available
558114
558626
  letta upgrade Alias for \`letta update\`
558115
- letta --update Alias for \`letta update\`
558116
- letta --upgrade Alias for \`letta update\`
558627
+ letta --update/--upgrade Aliases for \`letta update\`
558117
558628
  letta memory ... Memory filesystem subcommands
558118
558629
  letta agents ... Agents subcommands (JSON-only)
558119
558630
  letta environments ... List available remote environments (JSON-only)
558120
558631
  letta messages ... Messages subcommands (JSON-only)
558121
558632
  letta mods ... List and manage local mods
558633
+ letta sandbox ... Transfer files to or from the current Cloud sandbox
558122
558634
  letta server ... Run a remote environment, channels, or the App Server
558123
558635
  letta connect ... Connect providers from terminal
558124
558636
  letta backend ... Show or set the default backend
@@ -558703,9 +559215,9 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
558703
559215
  process.exit(1);
558704
559216
  }
558705
559217
  } else {
558706
- const { resolve: resolve40 } = await import("node:path");
559218
+ const { resolve: resolve41 } = await import("node:path");
558707
559219
  const { existsSync: existsSync71 } = await import("node:fs");
558708
- const resolvedPath = resolve40(fromAfFile);
559220
+ const resolvedPath = resolve41(fromAfFile);
558709
559221
  if (!existsSync71(resolvedPath)) {
558710
559222
  console.error(`Error: AgentFile not found: ${resolvedPath}`);
558711
559223
  process.exit(1);
@@ -561829,4 +562341,4 @@ function registerBunOAuthFlows() {
561829
562341
  registerBunOAuthFlows();
561830
562342
  await init_src5().then(() => exports_src2);
561831
562343
 
561832
- //# debugId=72DF88226DD9B50564756E2164756E21
562344
+ //# debugId=447A31644C59E2F264756E2164756E21