@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.
- package/letta.js +65 -39
- 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.
|
|
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
|
|
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
|
|
148359
|
+
const lines2 = [display.title, body];
|
|
148359
148360
|
if (display.runId) {
|
|
148360
|
-
|
|
148361
|
+
lines2.push("", `Run ID: ${display.runId}`);
|
|
148361
148362
|
}
|
|
148362
|
-
return
|
|
148363
|
+
return lines2.join(`
|
|
148363
148364
|
`);
|
|
148364
148365
|
}
|
|
148365
148366
|
if (options3.codeBlock) {
|
|
148366
148367
|
const escaped = body.replace(/```/g, "```");
|
|
148367
|
-
|
|
148368
|
-
|
|
148369
|
-
${
|
|
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
|
-
|
|
148373
|
-
|
|
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
|
-
|
|
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 (!
|
|
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=
|
|
532690
|
+
//# debugId=55BC4B9CDFA31DCE64756E2164756E21
|
package/package.json
CHANGED