@letta-ai/letta-code 0.27.21 → 0.27.22

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 (2) hide show
  1. package/letta.js +65 -39
  2. package/package.json +1 -1
package/letta.js CHANGED
@@ -4672,7 +4672,7 @@ var package_default;
4672
4672
  var init_package = __esm(() => {
4673
4673
  package_default = {
4674
4674
  name: "@letta-ai/letta-code",
4675
- version: "0.27.21",
4675
+ version: "0.27.22",
4676
4676
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
4677
4677
  type: "module",
4678
4678
  packageManager: "bun@1.3.0",
@@ -148318,7 +148318,8 @@ function truncateLifecycleMessage(text, maxLength3) {
148318
148318
  }
148319
148319
  function getChannelLifecycleErrorDisplay(errorText, options3 = {}) {
148320
148320
  const normalized = sanitizeChannelLifecycleErrorText(errorText);
148321
- const runId = extractChannelLifecycleRunId(errorText);
148321
+ const optionsRunId = options3.runId?.trim();
148322
+ const runId = optionsRunId || extractChannelLifecycleRunId(errorText);
148322
148323
  if (!normalized || RAW_LOOP_ERROR_PATTERN.test(normalized)) {
148323
148324
  return {
148324
148325
  kind: "generic",
@@ -148355,22 +148356,28 @@ function formatChannelLifecycleErrorMessage(errorText, options3 = {}) {
148355
148356
  const maxLength3 = options3.maxLength ?? Number.POSITIVE_INFINITY;
148356
148357
  const body = truncateLifecycleMessage(display.body, maxLength3);
148357
148358
  if (display.kind === "conversation_busy") {
148358
- const lines = [display.title, body];
148359
+ const lines2 = [display.title, body];
148359
148360
  if (display.runId) {
148360
- lines.push("", `Run ID: ${display.runId}`);
148361
+ lines2.push("", `Run ID: ${display.runId}`);
148361
148362
  }
148362
- return lines.join(`
148363
+ return lines2.join(`
148363
148364
  `);
148364
148365
  }
148365
148366
  if (options3.codeBlock) {
148366
148367
  const escaped = body.replace(/```/g, "``​`");
148367
- return `${display.title}:
148368
- \`\`\`
148369
- ${escaped}
148370
- \`\`\``;
148368
+ const lines2 = [`${display.title}:`, "```", escaped, "```"];
148369
+ if (display.runId) {
148370
+ lines2.push("", `Run ID: ${display.runId}`);
148371
+ }
148372
+ return lines2.join(`
148373
+ `);
148371
148374
  }
148372
- return `${display.title}:
148373
- ${body}`;
148375
+ const lines = [`${display.title}:`, body];
148376
+ if (display.runId) {
148377
+ lines.push("", `Run ID: ${display.runId}`);
148378
+ }
148379
+ return lines.join(`
148380
+ `);
148374
148381
  }
148375
148382
  var RAW_LOOP_ERROR_PATTERN, APP_CHAT_URL_PATTERN, ESCAPE_CHARACTER, OSC8_PREFIX, OSC8_TERMINATOR, APPROVAL_PENDING_ERROR_PATTERNS, RUN_ID_PATTERNS, CHANNEL_LIFECYCLE_FALLBACK_ERROR_MESSAGE = "Something went wrong while processing that message. Please try again.", CHANNEL_LIFECYCLE_APPROVAL_PENDING_MESSAGE = "The agent is still waiting on a tool approval from an earlier turn. Please approve or deny that pending request, then send your message again.", CHANNEL_LIFECYCLE_CONVERSATION_BUSY_TITLE;
148376
148383
  var init_lifecycle_error = __esm(() => {
@@ -148402,8 +148409,10 @@ function truncateReportMessage(message) {
148402
148409
  function withDefinedValues(payload) {
148403
148410
  return Object.fromEntries(Object.entries(payload).filter(([, value]) => value !== undefined));
148404
148411
  }
148405
- function buildChannelLifecycleErrorReport(source2, errorText) {
148406
- const display = getChannelLifecycleErrorDisplay(errorText);
148412
+ function buildChannelLifecycleErrorReport(source2, errorText, options3 = {}) {
148413
+ const display = getChannelLifecycleErrorDisplay(errorText, {
148414
+ runId: options3.runId
148415
+ });
148407
148416
  return {
148408
148417
  channel: source2.channel,
148409
148418
  accountId: source2.accountId,
@@ -149966,9 +149975,10 @@ function getTelegramLifecycleErrorReplyKey(source2) {
149966
149975
  source2.conversationId
149967
149976
  ].join(":");
149968
149977
  }
149969
- function formatTelegramLifecycleErrorMessage(errorText) {
149978
+ function formatTelegramLifecycleErrorMessage(errorText, runId) {
149970
149979
  return formatChannelLifecycleErrorMessage(errorText, {
149971
- maxLength: TELEGRAM_LIFECYCLE_ERROR_TEXT_MAX
149980
+ maxLength: TELEGRAM_LIFECYCLE_ERROR_TEXT_MAX,
149981
+ runId
149972
149982
  });
149973
149983
  }
149974
149984
  function createTelegramAdapter(config3) {
@@ -150312,12 +150322,12 @@ function createTelegramAdapter(config3) {
150312
150322
  }
150313
150323
  }
150314
150324
  }
150315
- function rememberLifecycleErrorReport(source2, errorText) {
150325
+ function rememberLifecycleErrorReport(source2, errorText, runId) {
150316
150326
  pruneLifecycleErrorReports();
150317
150327
  const token = randomUUID6();
150318
150328
  lifecycleErrorReports.set(token, {
150319
150329
  expiresAt: Date.now() + TELEGRAM_LIFECYCLE_ERROR_REPORT_TTL_MS,
150320
- report: buildChannelLifecycleErrorReport(source2, errorText),
150330
+ report: buildChannelLifecycleErrorReport(source2, errorText, { runId }),
150321
150331
  submitted: false
150322
150332
  });
150323
150333
  return `${TELEGRAM_REPORT_CALLBACK_PREFIX}${token}`;
@@ -150355,7 +150365,7 @@ function createTelegramAdapter(config3) {
150355
150365
  await answerLifecycleErrorReportCallback(callbackCtx, "Could not send the error report. Please try again later.", true);
150356
150366
  }
150357
150367
  }
150358
- async function sendLifecycleErrorReply(source2, errorText) {
150368
+ async function sendLifecycleErrorReply(source2, errorText, runId) {
150359
150369
  const key = getTelegramLifecycleErrorReplyKey(source2);
150360
150370
  if (!key || !rememberLifecycleErrorReply(key)) {
150361
150371
  return;
@@ -150379,12 +150389,12 @@ function createTelegramAdapter(config3) {
150379
150389
  [
150380
150390
  {
150381
150391
  text: "Report error",
150382
- callback_data: rememberLifecycleErrorReport(source2, errorText)
150392
+ callback_data: rememberLifecycleErrorReport(source2, errorText, runId)
150383
150393
  }
150384
150394
  ]
150385
150395
  ]
150386
150396
  };
150387
- await telegramBot.api.sendMessage(source2.chatId, formatTelegramLifecycleErrorMessage(errorText), options3);
150397
+ await telegramBot.api.sendMessage(source2.chatId, formatTelegramLifecycleErrorMessage(errorText, runId), options3);
150388
150398
  }
150389
150399
  const adapter = {
150390
150400
  id: `telegram:${config3.accountId}`,
@@ -150569,7 +150579,7 @@ function createTelegramAdapter(config3) {
150569
150579
  }
150570
150580
  await Promise.all(Array.from(uniqueSources.values()).map(async (source2) => {
150571
150581
  try {
150572
- await sendLifecycleErrorReply(source2, event2.error ?? "Turn failed");
150582
+ await sendLifecycleErrorReply(source2, event2.error ?? "Turn failed", event2.runId);
150573
150583
  } catch (error54) {
150574
150584
  console.warn(`[Telegram] Failed to send lifecycle error reply for ${source2.chatId}:`, error54 instanceof Error ? error54.message : error54);
150575
150585
  }
@@ -152632,10 +152642,11 @@ function createSlackAdapter(config3) {
152632
152642
  }
152633
152643
  return `${source2.chatId}:${replyToMessageId}`;
152634
152644
  }
152635
- function formatSlackLifecycleErrorMessage(errorText) {
152645
+ function formatSlackLifecycleErrorMessage(errorText, runId) {
152636
152646
  return formatChannelLifecycleErrorMessage(errorText, {
152637
152647
  codeBlock: true,
152638
- maxLength: SLACK_LIFECYCLE_ERROR_TEXT_MAX
152648
+ maxLength: SLACK_LIFECYCLE_ERROR_TEXT_MAX,
152649
+ runId
152639
152650
  });
152640
152651
  }
152641
152652
  function pruneLifecycleState(now = Date.now()) {
@@ -152676,7 +152687,7 @@ function createSlackAdapter(config3) {
152676
152687
  name: emoji3
152677
152688
  });
152678
152689
  }
152679
- async function sendLifecycleErrorReply(source2, errorText) {
152690
+ async function sendLifecycleErrorReply(source2, errorText, runId) {
152680
152691
  const replyToMessageId = source2.threadId ?? source2.messageId;
152681
152692
  if (!isNonEmptyString3(replyToMessageId)) {
152682
152693
  return;
@@ -152685,7 +152696,7 @@ function createSlackAdapter(config3) {
152685
152696
  const slackClient = await ensureWriteClient();
152686
152697
  const response = await slackClient.chat.postMessage({
152687
152698
  channel: source2.chatId,
152688
- text: formatSlackLifecycleErrorMessage(errorText),
152699
+ text: formatSlackLifecycleErrorMessage(errorText, runId),
152689
152700
  thread_ts: replyToMessageId
152690
152701
  });
152691
152702
  rememberMessageThread(response.ts, replyToMessageId);
@@ -153107,7 +153118,7 @@ function createSlackAdapter(config3) {
153107
153118
  }
153108
153119
  await Promise.all(Array.from(uniqueReplySources.values()).map(async (source2) => {
153109
153120
  try {
153110
- await sendLifecycleErrorReply(source2, errorText);
153121
+ await sendLifecycleErrorReply(source2, errorText, event2.runId);
153111
153122
  } catch (error54) {
153112
153123
  console.warn(`[Slack] Failed to post lifecycle error for ${source2.chatId}:`, error54 instanceof Error ? error54.message : error54);
153113
153124
  }
@@ -154157,10 +154168,11 @@ function buildDiscordReplyOptions(replyToMessageId, channelId) {
154157
154168
  }
154158
154169
  };
154159
154170
  }
154160
- function formatDiscordLifecycleErrorMessage(errorText) {
154171
+ function formatDiscordLifecycleErrorMessage(errorText, runId) {
154161
154172
  return formatChannelLifecycleErrorMessage(errorText, {
154162
154173
  codeBlock: true,
154163
- maxLength: DISCORD_LIFECYCLE_ERROR_TEXT_MAX
154174
+ maxLength: DISCORD_LIFECYCLE_ERROR_TEXT_MAX,
154175
+ runId
154164
154176
  });
154165
154177
  }
154166
154178
  async function notifyDiscordDeliveryError(message, error54) {
@@ -154324,7 +154336,7 @@ function createDiscordAdapter(config3) {
154324
154336
  console.warn(`[Discord] Failed to ${remove ? "remove" : "add"} lifecycle reaction:`, error54 instanceof Error ? error54.message : error54);
154325
154337
  }
154326
154338
  }
154327
- async function sendLifecycleErrorReply(source2, errorText) {
154339
+ async function sendLifecycleErrorReply(source2, errorText, runId) {
154328
154340
  if (!client)
154329
154341
  return;
154330
154342
  const key = getLifecycleReplyKey(source2);
@@ -154339,7 +154351,7 @@ function createDiscordAdapter(config3) {
154339
154351
  const reply = buildDiscordReplyOptions(source2.messageId, targetChannelId);
154340
154352
  await channel.send({
154341
154353
  allowedMentions: { parse: [] },
154342
- content: formatDiscordLifecycleErrorMessage(errorText),
154354
+ content: formatDiscordLifecycleErrorMessage(errorText, runId),
154343
154355
  ...reply ?? {}
154344
154356
  });
154345
154357
  }
@@ -154758,7 +154770,7 @@ function createDiscordAdapter(config3) {
154758
154770
  }
154759
154771
  await Promise.all(Array.from(uniqueReplySources.values()).map(async (source2) => {
154760
154772
  try {
154761
- await sendLifecycleErrorReply(source2, errorText);
154773
+ await sendLifecycleErrorReply(source2, errorText, event2.runId);
154762
154774
  } catch (error54) {
154763
154775
  console.warn(`[Discord] Failed to post lifecycle error for ${source2.chatId}:`, error54 instanceof Error ? error54.message : error54);
154764
154776
  }
@@ -156301,9 +156313,9 @@ function createWhatsAppAdapter(account) {
156301
156313
  }
156302
156314
  await Promise.all(Array.from(uniqueSources.values()).map(async (source2) => {
156303
156315
  try {
156304
- await adapter.sendDirectReply(source2.chatId, errorText, {
156305
- replyToMessageId: source2.messageId
156306
- });
156316
+ await adapter.sendDirectReply(source2.chatId, formatChannelLifecycleErrorMessage(errorText, {
156317
+ runId: event2.runId
156318
+ }), { replyToMessageId: source2.messageId });
156307
156319
  } catch (error54) {
156308
156320
  console.warn(`[WhatsApp:${account.accountId}] Failed to send lifecycle error reply for ${source2.chatId}:`, error54 instanceof Error ? error54.message : error54);
156309
156321
  }
@@ -156314,6 +156326,7 @@ function createWhatsAppAdapter(account) {
156314
156326
  }
156315
156327
  var CHANNEL_ID = "whatsapp", DEDUPE_MAX_SIZE = 5000, RECONNECT_MAX_MS = 30000, MAX_MENTION_PATTERN_LENGTH = 256, MENTION_MATCH_TEXT_MAX_LENGTH = 2000;
156316
156328
  var init_adapter5 = __esm(() => {
156329
+ init_lifecycle_error();
156317
156330
  init_media4();
156318
156331
  init_runtime4();
156319
156332
  init_session();
@@ -166503,6 +166516,7 @@ function createConversationRuntime(listener, agentId, conversationId) {
166503
166516
  recoveredApprovalState: null,
166504
166517
  lastStopReason: null,
166505
166518
  lastTerminalLoopErrorMessage: null,
166519
+ lastTerminalLoopErrorRunId: null,
166506
166520
  isProcessing: false,
166507
166521
  activeWorkingDirectory: null,
166508
166522
  expectedWorktreePath: null,
@@ -167924,6 +167938,10 @@ function isFsSandboxEnabled(env3 = process.env) {
167924
167938
  const value = env3.LETTA_FS_SANDBOX?.trim().toLowerCase();
167925
167939
  return value !== "0" && value !== "false";
167926
167940
  }
167941
+ function isShellSandboxEnabled(env3 = process.env) {
167942
+ const value = env3.LETTA_FS_SANDBOX?.trim().toLowerCase();
167943
+ return value === "1" || value === "true";
167944
+ }
167927
167945
  function warnSandboxBackendUnavailable(availability, context2) {
167928
167946
  if (availability.backend)
167929
167947
  return;
@@ -168249,7 +168267,7 @@ var init_sandbox_policy = __esm(() => {
168249
168267
 
168250
168268
  // src/permissions/sandbox-gate.ts
168251
168269
  function resolveShellSandboxContext(cwd, env3, availability) {
168252
- if (!isFsSandboxEnabled(env3))
168270
+ if (!isShellSandboxEnabled(env3))
168253
168271
  return null;
168254
168272
  if (env3[SANDBOX_ENV_VAR])
168255
168273
  return null;
@@ -424290,7 +424308,8 @@ async function dispatchChannelTurnLifecycleEvent(event2) {
424290
424308
  batchId: event2.batchId,
424291
424309
  sources: event2.sources,
424292
424310
  outcome: event2.outcome,
424293
- ...event2.error ? { error: event2.error } : {}
424311
+ ...event2.error ? { error: event2.error } : {},
424312
+ ...event2.runId ? { runId: event2.runId } : {}
424294
424313
  });
424295
424314
  }
424296
424315
  function mapTurnLifecycleOutcome(lastStopReason, didThrow) {
@@ -424532,7 +424551,8 @@ async function drainQueuedMessages(runtime, socket, opts, processQueuedTurn) {
424532
424551
  batchId: dequeuedBatch.batchId,
424533
424552
  sources: channelTurnSources,
424534
424553
  outcome,
424535
- ...lifecycleError ? { error: lifecycleError } : {}
424554
+ ...lifecycleError ? { error: lifecycleError } : {},
424555
+ ...runtime.lastTerminalLoopErrorRunId ? { runId: runtime.lastTerminalLoopErrorRunId } : {}
424536
424556
  });
424537
424557
  }
424538
424558
  }
@@ -438807,6 +438827,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
438807
438827
  runtime.cancelRequested = false;
438808
438828
  runtime.lastStopReason = null;
438809
438829
  runtime.lastTerminalLoopErrorMessage = null;
438830
+ runtime.lastTerminalLoopErrorRunId = null;
438810
438831
  const turnAbortController = new AbortController;
438811
438832
  runtime.activeAbortController = turnAbortController;
438812
438833
  const turnAbortSignal = turnAbortController.signal;
@@ -439338,11 +439359,12 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
439338
439359
  conversation_id: conversationId
439339
439360
  });
439340
439361
  const errorMessage = errorDetail || `Unexpected stop reason: ${stopReason}`;
439362
+ const terminalRunId = runId || runtime.activeRunId || runErrorInfo2?.run_id;
439341
439363
  const formattedError = emitLoopErrorNotice(socket, runtime, {
439342
439364
  message: errorMessage,
439343
439365
  stopReason: effectiveStopReason,
439344
439366
  isTerminal: true,
439345
- runId,
439367
+ runId: terminalRunId,
439346
439368
  agentId,
439347
439369
  conversationId,
439348
439370
  runErrorInfo: runErrorInfo2 ?? undefined,
@@ -439350,6 +439372,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
439350
439372
  abortSignal: turnAbortSignal
439351
439373
  });
439352
439374
  runtime.lastTerminalLoopErrorMessage = formattedError ?? errorMessage;
439375
+ runtime.lastTerminalLoopErrorRunId = terminalRunId ?? null;
439353
439376
  break;
439354
439377
  }
439355
439378
  const approvalResult = await handleApprovalStop({
@@ -439433,10 +439456,12 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
439433
439456
  conversation_id: conversationId
439434
439457
  });
439435
439458
  const errorMessage = error54 instanceof Error ? error54.message : String(error54);
439459
+ const terminalRunId = runtime.activeRunId;
439436
439460
  const formattedError = emitLoopErrorNotice(socket, runtime, {
439437
439461
  message: errorMessage,
439438
439462
  stopReason: "error",
439439
439463
  isTerminal: true,
439464
+ runId: terminalRunId,
439440
439465
  agentId: agentId || undefined,
439441
439466
  conversationId,
439442
439467
  error: error54,
@@ -439444,6 +439469,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
439444
439469
  abortSignal: turnAbortSignal
439445
439470
  });
439446
439471
  runtime.lastTerminalLoopErrorMessage = formattedError ?? errorMessage;
439472
+ runtime.lastTerminalLoopErrorRunId = terminalRunId ?? null;
439447
439473
  if (isDebugEnabled()) {
439448
439474
  console.error("[Listen] Error handling message:", error54);
439449
439475
  }
@@ -532661,4 +532687,4 @@ Error during initialization: ${message}`);
532661
532687
  }
532662
532688
  main2();
532663
532689
 
532664
- //# debugId=686CCE3851FAA0F364756E2164756E21
532690
+ //# debugId=55BC4B9CDFA31DCE64756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letta-ai/letta-code",
3
- "version": "0.27.21",
3
+ "version": "0.27.22",
4
4
  "description": "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
5
5
  "type": "module",
6
6
  "packageManager": "bun@1.3.0",