@letta-ai/letta-code 0.21.14 → 0.21.16
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 +442 -509
- package/package.json +1 -1
package/letta.js
CHANGED
|
@@ -3269,7 +3269,7 @@ var package_default;
|
|
|
3269
3269
|
var init_package = __esm(() => {
|
|
3270
3270
|
package_default = {
|
|
3271
3271
|
name: "@letta-ai/letta-code",
|
|
3272
|
-
version: "0.21.
|
|
3272
|
+
version: "0.21.16",
|
|
3273
3273
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
3274
3274
|
type: "module",
|
|
3275
3275
|
bin: {
|
|
@@ -5311,12 +5311,6 @@ var approval_recovery_alert_default = `<system-reminder>Automated keep-alive pin
|
|
|
5311
5311
|
`;
|
|
5312
5312
|
var init_approval_recovery_alert = () => {};
|
|
5313
5313
|
|
|
5314
|
-
// src/agent/prompts/auto_init_reminder.txt
|
|
5315
|
-
var auto_init_reminder_default = `<system-reminder>
|
|
5316
|
-
A background agent is initializing this agent's memory system. Briefly let the user know that memory is being set up in the background, then respond to their message normally.
|
|
5317
|
-
</system-reminder>`;
|
|
5318
|
-
var init_auto_init_reminder = () => {};
|
|
5319
|
-
|
|
5320
5314
|
// src/agent/prompts/human.mdx
|
|
5321
5315
|
var human_default = `---
|
|
5322
5316
|
label: human
|
|
@@ -7871,7 +7865,6 @@ __export(exports_promptAssets, {
|
|
|
7871
7865
|
MEMORY_PROMPTS: () => MEMORY_PROMPTS,
|
|
7872
7866
|
MEMORY_CHECK_REMINDER: () => MEMORY_CHECK_REMINDER,
|
|
7873
7867
|
INTERRUPT_RECOVERY_ALERT: () => INTERRUPT_RECOVERY_ALERT,
|
|
7874
|
-
AUTO_INIT_REMINDER: () => AUTO_INIT_REMINDER,
|
|
7875
7868
|
APPROVAL_RECOVERY_PROMPT: () => APPROVAL_RECOVERY_PROMPT
|
|
7876
7869
|
});
|
|
7877
7870
|
function scanHeadingsOutsideFences(text) {
|
|
@@ -8002,10 +7995,9 @@ async function resolveSystemPrompt(systemPromptPreset) {
|
|
|
8002
7995
|
}
|
|
8003
7996
|
throw new Error(`Unknown system prompt "${systemPromptPreset}" — does not match any preset or subagent`);
|
|
8004
7997
|
}
|
|
8005
|
-
var SYSTEM_PROMPT, SYSTEM_PROMPT_BLOCKS_ADDON, SYSTEM_PROMPT_MEMFS_ADDON, PLAN_MODE_REMINDER, SKILL_CREATOR_PROMPT, REMEMBER_PROMPT, MEMORY_CHECK_REMINDER, APPROVAL_RECOVERY_PROMPT,
|
|
7998
|
+
var SYSTEM_PROMPT, SYSTEM_PROMPT_BLOCKS_ADDON, SYSTEM_PROMPT_MEMFS_ADDON, PLAN_MODE_REMINDER, SKILL_CREATOR_PROMPT, REMEMBER_PROMPT, MEMORY_CHECK_REMINDER, APPROVAL_RECOVERY_PROMPT, INTERRUPT_RECOVERY_ALERT, SLEEPTIME_MEMORY_PERSONA, MEMORY_PROMPTS, SYSTEM_PROMPTS;
|
|
8006
7999
|
var init_promptAssets = __esm(() => {
|
|
8007
8000
|
init_approval_recovery_alert();
|
|
8008
|
-
init_auto_init_reminder();
|
|
8009
8001
|
init_human();
|
|
8010
8002
|
init_human_kawaii();
|
|
8011
8003
|
init_human_linus();
|
|
@@ -8037,7 +8029,6 @@ var init_promptAssets = __esm(() => {
|
|
|
8037
8029
|
REMEMBER_PROMPT = remember_default;
|
|
8038
8030
|
MEMORY_CHECK_REMINDER = memory_check_reminder_default;
|
|
8039
8031
|
APPROVAL_RECOVERY_PROMPT = approval_recovery_alert_default;
|
|
8040
|
-
AUTO_INIT_REMINDER = auto_init_reminder_default;
|
|
8041
8032
|
INTERRUPT_RECOVERY_ALERT = interrupt_recovery_alert_default;
|
|
8042
8033
|
SLEEPTIME_MEMORY_PERSONA = sleeptime_default;
|
|
8043
8034
|
MEMORY_PROMPTS = {
|
|
@@ -38319,6 +38310,7 @@ __export(exports_memoryGit, {
|
|
|
38319
38310
|
pushMemory: () => pushMemory,
|
|
38320
38311
|
pullMemory: () => pullMemory,
|
|
38321
38312
|
normalizeCredentialBaseUrl: () => normalizeCredentialBaseUrl,
|
|
38313
|
+
isRetryableGitTransientError: () => isRetryableGitTransientError,
|
|
38322
38314
|
isGitRepo: () => isGitRepo,
|
|
38323
38315
|
getMemoryRepoDir: () => getMemoryRepoDir,
|
|
38324
38316
|
getMemoryGitStatus: () => getMemoryGitStatus,
|
|
@@ -38381,6 +38373,35 @@ async function runGit(cwd2, args, token) {
|
|
|
38381
38373
|
stderr: result.stderr?.toString() ?? ""
|
|
38382
38374
|
};
|
|
38383
38375
|
}
|
|
38376
|
+
function isRetryableGitTransientError(error) {
|
|
38377
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
38378
|
+
if (RETRYABLE_GIT_HTTP_ERROR_RE.test(message)) {
|
|
38379
|
+
return true;
|
|
38380
|
+
}
|
|
38381
|
+
if (message.includes("RPC failed") && RETRYABLE_GIT_NETWORK_ERROR_RE.test(message)) {
|
|
38382
|
+
return true;
|
|
38383
|
+
}
|
|
38384
|
+
return false;
|
|
38385
|
+
}
|
|
38386
|
+
async function runGitWithRetry(cwd2, args, token, options) {
|
|
38387
|
+
const attempts = options?.attempts ?? 3;
|
|
38388
|
+
const baseDelayMs = options?.baseDelayMs ?? 500;
|
|
38389
|
+
const operation = options?.operation ?? args[0] ?? "git op";
|
|
38390
|
+
for (let attempt = 1;attempt <= attempts; attempt += 1) {
|
|
38391
|
+
try {
|
|
38392
|
+
return await runGit(cwd2, args, token);
|
|
38393
|
+
} catch (error) {
|
|
38394
|
+
if (!isRetryableGitTransientError(error) || attempt >= attempts) {
|
|
38395
|
+
throw error;
|
|
38396
|
+
}
|
|
38397
|
+
const delayMs = baseDelayMs * 2 ** (attempt - 1);
|
|
38398
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
38399
|
+
debugWarn("memfs-git", `${operation} failed with transient error (attempt ${attempt}/${attempts}): ${msg}. Retrying in ${delayMs}ms`);
|
|
38400
|
+
await new Promise((resolve2) => setTimeout(resolve2, delayMs));
|
|
38401
|
+
}
|
|
38402
|
+
}
|
|
38403
|
+
throw new Error(`Unexpected retry loop exit for ${operation}`);
|
|
38404
|
+
}
|
|
38384
38405
|
async function configureLocalCredentialHelper(dir, token) {
|
|
38385
38406
|
const rawBaseUrl = getServerUrl();
|
|
38386
38407
|
const normalizedBaseUrl = normalizeCredentialBaseUrl(rawBaseUrl);
|
|
@@ -38415,7 +38436,9 @@ async function cloneMemoryRepo(agentId) {
|
|
|
38415
38436
|
debugLog("memfs-git", `Cloning ${url} → ${dir}`);
|
|
38416
38437
|
if (!existsSync8(dir)) {
|
|
38417
38438
|
mkdirSync6(dir, { recursive: true });
|
|
38418
|
-
await
|
|
38439
|
+
await runGitWithRetry(dir, ["clone", url, "."], token, {
|
|
38440
|
+
operation: "clone memory repo"
|
|
38441
|
+
});
|
|
38419
38442
|
} else if (!existsSync8(join7(dir, ".git"))) {
|
|
38420
38443
|
const tmpDir = `${dir}-git-clone-tmp`;
|
|
38421
38444
|
try {
|
|
@@ -38423,7 +38446,9 @@ async function cloneMemoryRepo(agentId) {
|
|
|
38423
38446
|
rmSync(tmpDir, { recursive: true, force: true });
|
|
38424
38447
|
}
|
|
38425
38448
|
mkdirSync6(tmpDir, { recursive: true });
|
|
38426
|
-
await
|
|
38449
|
+
await runGitWithRetry(tmpDir, ["clone", url, "."], token, {
|
|
38450
|
+
operation: "clone memory repo (tmp migration)"
|
|
38451
|
+
});
|
|
38427
38452
|
renameSync(join7(tmpDir, ".git"), join7(dir, ".git"));
|
|
38428
38453
|
await runGit(dir, ["checkout", "--", "."], token);
|
|
38429
38454
|
debugLog("memfs-git", "Migrated existing memory directory to git repo");
|
|
@@ -38442,7 +38467,7 @@ async function pullMemory(agentId) {
|
|
|
38442
38467
|
await configureLocalCredentialHelper(dir, token);
|
|
38443
38468
|
installPreCommitHook(dir);
|
|
38444
38469
|
try {
|
|
38445
|
-
const { stdout, stderr } = await
|
|
38470
|
+
const { stdout, stderr } = await runGitWithRetry(dir, ["pull", "--ff-only"], token, { operation: "pull --ff-only" });
|
|
38446
38471
|
const output = stdout + stderr;
|
|
38447
38472
|
const updated = !output.includes("Already up to date");
|
|
38448
38473
|
return {
|
|
@@ -38452,7 +38477,7 @@ async function pullMemory(agentId) {
|
|
|
38452
38477
|
} catch {
|
|
38453
38478
|
debugWarn("memfs-git", "Fast-forward pull failed, trying rebase");
|
|
38454
38479
|
try {
|
|
38455
|
-
const { stdout, stderr } = await
|
|
38480
|
+
const { stdout, stderr } = await runGitWithRetry(dir, ["pull", "--rebase"], token, { operation: "pull --rebase" });
|
|
38456
38481
|
return { updated: true, summary: (stdout + stderr).trim() };
|
|
38457
38482
|
} catch (rebaseErr) {
|
|
38458
38483
|
const msg = rebaseErr instanceof Error ? rebaseErr.message : String(rebaseErr);
|
|
@@ -38548,7 +38573,7 @@ async function removeGitMemoryTag(agentId) {
|
|
|
38548
38573
|
debugWarn("memfs-git", `Failed to remove git-memory tag: ${err instanceof Error ? err.message : String(err)}`);
|
|
38549
38574
|
}
|
|
38550
38575
|
}
|
|
38551
|
-
var execFile, GIT_MEMORY_ENABLED_TAG = "git-memory-enabled", PRE_COMMIT_HOOK_SCRIPT = `#!/usr/bin/env bash
|
|
38576
|
+
var execFile, GIT_MEMORY_ENABLED_TAG = "git-memory-enabled", RETRYABLE_GIT_HTTP_ERROR_RE, RETRYABLE_GIT_NETWORK_ERROR_RE, PRE_COMMIT_HOOK_SCRIPT = `#!/usr/bin/env bash
|
|
38552
38577
|
# Validate frontmatter in staged memory .md files
|
|
38553
38578
|
# Installed by Letta Code CLI
|
|
38554
38579
|
|
|
@@ -38686,6 +38711,8 @@ var init_memoryGit = __esm(async () => {
|
|
|
38686
38711
|
init_debug();
|
|
38687
38712
|
await init_client2();
|
|
38688
38713
|
execFile = promisify(execFileCb);
|
|
38714
|
+
RETRYABLE_GIT_HTTP_ERROR_RE = /(?:\bHTTP\s+(?:520|521|522|523|524)\b|The requested URL returned error:\s*(?:520|521|522|523|524))/i;
|
|
38715
|
+
RETRYABLE_GIT_NETWORK_ERROR_RE = /(remote end hung up unexpectedly|connection reset by peer|operation timed out|timed out)/i;
|
|
38689
38716
|
});
|
|
38690
38717
|
|
|
38691
38718
|
// src/agent/personality.ts
|
|
@@ -57464,7 +57491,6 @@ function createSharedReminderState() {
|
|
|
57464
57491
|
lastNotifiedPermissionMode: null,
|
|
57465
57492
|
turnCount: 0,
|
|
57466
57493
|
pendingReflectionTrigger: false,
|
|
57467
|
-
pendingAutoInitReminder: false,
|
|
57468
57494
|
pendingCommandIoReminders: [],
|
|
57469
57495
|
pendingToolsetChangeReminders: []
|
|
57470
57496
|
};
|
|
@@ -73037,13 +73063,6 @@ var init_memoryFilesystem = __esm(() => {
|
|
|
73037
73063
|
});
|
|
73038
73064
|
|
|
73039
73065
|
// src/cli/helpers/initCommand.ts
|
|
73040
|
-
import { execSync as execSync2 } from "node:child_process";
|
|
73041
|
-
import { existsSync as existsSync19, readdirSync as readdirSync8, readFileSync as readFileSync11 } from "node:fs";
|
|
73042
|
-
import { join as join23 } from "node:path";
|
|
73043
|
-
function hasActiveInitSubagent() {
|
|
73044
|
-
const snapshot = getSnapshot2();
|
|
73045
|
-
return snapshot.agents.some((agent) => agent.type.toLowerCase() === "init" && (agent.status === "pending" || agent.status === "running"));
|
|
73046
|
-
}
|
|
73047
73066
|
function gatherInitGitContext() {
|
|
73048
73067
|
try {
|
|
73049
73068
|
const git = gatherGitContextSnapshot({
|
|
@@ -73072,154 +73091,6 @@ ${git.recentCommits || "No commits yet"}
|
|
|
73072
73091
|
};
|
|
73073
73092
|
}
|
|
73074
73093
|
}
|
|
73075
|
-
function gatherExistingMemory(agentId) {
|
|
73076
|
-
const systemDir = getMemorySystemDir(agentId);
|
|
73077
|
-
if (!existsSync19(systemDir))
|
|
73078
|
-
return { paths: [], contents: "" };
|
|
73079
|
-
const paths = [];
|
|
73080
|
-
const sections = [];
|
|
73081
|
-
function walk(dir, prefix) {
|
|
73082
|
-
try {
|
|
73083
|
-
for (const entry of readdirSync8(dir, { withFileTypes: true })) {
|
|
73084
|
-
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
73085
|
-
if (entry.isDirectory()) {
|
|
73086
|
-
walk(join23(dir, entry.name), rel);
|
|
73087
|
-
} else if (entry.name.endsWith(".md")) {
|
|
73088
|
-
try {
|
|
73089
|
-
const content = readFileSync11(join23(dir, entry.name), "utf-8");
|
|
73090
|
-
paths.push(rel);
|
|
73091
|
-
sections.push(`── ${rel}
|
|
73092
|
-
${content.slice(0, 2000)}`);
|
|
73093
|
-
} catch {}
|
|
73094
|
-
}
|
|
73095
|
-
}
|
|
73096
|
-
} catch {}
|
|
73097
|
-
}
|
|
73098
|
-
walk(systemDir, "");
|
|
73099
|
-
return { paths, contents: sections.join(`
|
|
73100
|
-
|
|
73101
|
-
`) };
|
|
73102
|
-
}
|
|
73103
|
-
function getGitIgnored(cwd2, names) {
|
|
73104
|
-
if (names.length === 0)
|
|
73105
|
-
return new Set;
|
|
73106
|
-
try {
|
|
73107
|
-
const result = execSync2("git check-ignore --stdin", {
|
|
73108
|
-
cwd: cwd2,
|
|
73109
|
-
encoding: "utf-8",
|
|
73110
|
-
input: names.join(`
|
|
73111
|
-
`)
|
|
73112
|
-
}).trim();
|
|
73113
|
-
return new Set(result.split(`
|
|
73114
|
-
`).filter(Boolean));
|
|
73115
|
-
} catch {
|
|
73116
|
-
return new Set([
|
|
73117
|
-
"node_modules",
|
|
73118
|
-
"dist",
|
|
73119
|
-
"build",
|
|
73120
|
-
"__pycache__",
|
|
73121
|
-
"target",
|
|
73122
|
-
"vendor"
|
|
73123
|
-
]);
|
|
73124
|
-
}
|
|
73125
|
-
}
|
|
73126
|
-
function gatherDirListing() {
|
|
73127
|
-
const cwd2 = process.cwd();
|
|
73128
|
-
try {
|
|
73129
|
-
const entries = readdirSync8(cwd2, { withFileTypes: true });
|
|
73130
|
-
const visible = entries.filter((e) => !e.name.startsWith("."));
|
|
73131
|
-
const ignored = getGitIgnored(cwd2, visible.map((e) => e.name));
|
|
73132
|
-
const dirs = visible.filter((e) => e.isDirectory() && !ignored.has(e.name)).sort((a, b) => a.name.localeCompare(b.name));
|
|
73133
|
-
const files = visible.filter((e) => !e.isDirectory() && !ignored.has(e.name)).sort((a, b) => a.name.localeCompare(b.name));
|
|
73134
|
-
const lines = [];
|
|
73135
|
-
const sorted = [...dirs, ...files];
|
|
73136
|
-
for (const [i, entry] of sorted.entries()) {
|
|
73137
|
-
const isLast = i === sorted.length - 1;
|
|
73138
|
-
const prefix = isLast ? "└── " : "├── ";
|
|
73139
|
-
if (entry.isDirectory()) {
|
|
73140
|
-
lines.push(`${prefix}${entry.name}/`);
|
|
73141
|
-
try {
|
|
73142
|
-
const dirPath = join23(cwd2, entry.name);
|
|
73143
|
-
const childEntries = readdirSync8(dirPath, {
|
|
73144
|
-
withFileTypes: true
|
|
73145
|
-
}).filter((e) => !e.name.startsWith("."));
|
|
73146
|
-
const childIgnored = getGitIgnored(dirPath, childEntries.map((e) => e.name));
|
|
73147
|
-
const children = childEntries.filter((e) => !childIgnored.has(e.name)).sort((a, b) => {
|
|
73148
|
-
if (a.isDirectory() !== b.isDirectory())
|
|
73149
|
-
return a.isDirectory() ? -1 : 1;
|
|
73150
|
-
return a.name.localeCompare(b.name);
|
|
73151
|
-
});
|
|
73152
|
-
const childPrefix = isLast ? " " : "│ ";
|
|
73153
|
-
for (const [j, child] of children.entries()) {
|
|
73154
|
-
const childIsLast = j === children.length - 1;
|
|
73155
|
-
const connector = childIsLast ? "└── " : "├── ";
|
|
73156
|
-
const suffix = child.isDirectory() ? "/" : "";
|
|
73157
|
-
lines.push(`${childPrefix}${connector}${child.name}${suffix}`);
|
|
73158
|
-
}
|
|
73159
|
-
} catch {}
|
|
73160
|
-
} else {
|
|
73161
|
-
lines.push(`${prefix}${entry.name}`);
|
|
73162
|
-
}
|
|
73163
|
-
}
|
|
73164
|
-
return lines.join(`
|
|
73165
|
-
`);
|
|
73166
|
-
} catch {
|
|
73167
|
-
return "";
|
|
73168
|
-
}
|
|
73169
|
-
}
|
|
73170
|
-
function buildShallowInitPrompt(args) {
|
|
73171
|
-
const identityLine = args.gitIdentity ? `- git_user: ${args.gitIdentity}` : "";
|
|
73172
|
-
return `
|
|
73173
|
-
## Environment
|
|
73174
|
-
|
|
73175
|
-
- working_directory: ${args.workingDirectory}
|
|
73176
|
-
- memory_dir: ${args.memoryDir}
|
|
73177
|
-
- parent_agent_id: ${args.agentId}
|
|
73178
|
-
${identityLine}
|
|
73179
|
-
|
|
73180
|
-
## Project Structure
|
|
73181
|
-
|
|
73182
|
-
\`\`\`
|
|
73183
|
-
${args.dirListing}
|
|
73184
|
-
\`\`\`
|
|
73185
|
-
|
|
73186
|
-
## Existing Memory
|
|
73187
|
-
|
|
73188
|
-
${args.existingMemoryPaths.length > 0 ? `Paths:
|
|
73189
|
-
${args.existingMemoryPaths.map((p) => `- ${p}`).join(`
|
|
73190
|
-
`)}
|
|
73191
|
-
|
|
73192
|
-
Contents:
|
|
73193
|
-
${args.existingMemory}` : "(empty)"}
|
|
73194
|
-
`.trim();
|
|
73195
|
-
}
|
|
73196
|
-
async function fireAutoInit(agentId, onComplete) {
|
|
73197
|
-
if (hasActiveInitSubagent())
|
|
73198
|
-
return false;
|
|
73199
|
-
if (!settingsManager.isMemfsEnabled(agentId))
|
|
73200
|
-
return false;
|
|
73201
|
-
const gitDetails = gatherInitGitContext();
|
|
73202
|
-
const existing = gatherExistingMemory(agentId);
|
|
73203
|
-
const dirListing = gatherDirListing();
|
|
73204
|
-
const initPrompt = buildShallowInitPrompt({
|
|
73205
|
-
agentId,
|
|
73206
|
-
workingDirectory: process.cwd(),
|
|
73207
|
-
memoryDir: getMemoryFilesystemRoot(agentId),
|
|
73208
|
-
gitIdentity: gitDetails.identity,
|
|
73209
|
-
existingMemoryPaths: existing.paths,
|
|
73210
|
-
existingMemory: existing.contents,
|
|
73211
|
-
dirListing
|
|
73212
|
-
});
|
|
73213
|
-
const { spawnBackgroundSubagentTask: spawnBackgroundSubagentTask2 } = await init_Task2().then(() => exports_Task);
|
|
73214
|
-
spawnBackgroundSubagentTask2({
|
|
73215
|
-
subagentType: "init",
|
|
73216
|
-
prompt: initPrompt,
|
|
73217
|
-
description: "Initializing memory",
|
|
73218
|
-
silentCompletion: true,
|
|
73219
|
-
onComplete
|
|
73220
|
-
});
|
|
73221
|
-
return true;
|
|
73222
|
-
}
|
|
73223
73094
|
function buildInitMessage(args) {
|
|
73224
73095
|
const memfsSection = args.memoryDir ? `
|
|
73225
73096
|
## Memory filesystem
|
|
@@ -73265,12 +73136,10 @@ Once invoked, follow the instructions from the \`context_doctor\` skill.
|
|
|
73265
73136
|
${args.gitContext}
|
|
73266
73137
|
${SYSTEM_REMINDER_CLOSE}`;
|
|
73267
73138
|
}
|
|
73268
|
-
var init_initCommand = __esm(
|
|
73269
|
-
init_memoryFilesystem();
|
|
73139
|
+
var init_initCommand = __esm(() => {
|
|
73270
73140
|
init_constants();
|
|
73271
73141
|
init_gitContext();
|
|
73272
73142
|
init_subagentState();
|
|
73273
|
-
await init_settings_manager();
|
|
73274
73143
|
});
|
|
73275
73144
|
|
|
73276
73145
|
// src/cli/helpers/errorFormatter.ts
|
|
@@ -73286,6 +73155,9 @@ function isCloudflareEdge52xHtmlError2(text) {
|
|
|
73286
73155
|
const has52xCode = CLOUDFLARE_EDGE_5XX_MARKER_PATTERN2.test(text) || CLOUDFLARE_EDGE_5XX_TITLE_PATTERN2.test(text);
|
|
73287
73156
|
return hasCloudflare && hasHtml && has52xCode;
|
|
73288
73157
|
}
|
|
73158
|
+
function isCloudflareEdge52xErrorText(text) {
|
|
73159
|
+
return CLOUDFLARE_EDGE_5XX_FORMATTED_PATTERN.test(text) || isCloudflareEdge52xHtmlError2(text);
|
|
73160
|
+
}
|
|
73289
73161
|
function parseCloudflareEdgeError2(text) {
|
|
73290
73162
|
if (!isCloudflareEdge52xHtmlError2(text))
|
|
73291
73163
|
return;
|
|
@@ -73638,7 +73510,7 @@ Upgrade at: ${LETTA_USAGE_URL2}
|
|
|
73638
73510
|
Delete ${resourceType} at: ${LETTA_AGENTS_URL2}`;
|
|
73639
73511
|
}
|
|
73640
73512
|
if (isCreditExhaustedError2(e, reasons)) {
|
|
73641
|
-
return `Your account
|
|
73513
|
+
return `Your account does not have credits for this model. Add your own API keys or upgrade your plan to purchase credits.`;
|
|
73642
73514
|
}
|
|
73643
73515
|
const tierUsageLimitMsg = getTierUsageLimitMessage2(reasons);
|
|
73644
73516
|
if (tierUsageLimitMsg)
|
|
@@ -73704,7 +73576,7 @@ ${createAgentLink2(runId, agentId, conversationId)}` : baseError;
|
|
|
73704
73576
|
function getRetryStatusMessage(errorDetail) {
|
|
73705
73577
|
if (!errorDetail)
|
|
73706
73578
|
return DEFAULT_RETRY_MESSAGE;
|
|
73707
|
-
if (
|
|
73579
|
+
if (isCloudflareEdge52xErrorText(errorDetail))
|
|
73708
73580
|
return null;
|
|
73709
73581
|
if (checkZaiError(errorDetail))
|
|
73710
73582
|
return "Z.ai API error, retrying...";
|
|
@@ -73731,7 +73603,7 @@ function createAgentLink2(runId, agentId, conversationId) {
|
|
|
73731
73603
|
const url = buildChatUrl(agentId, { conversationId });
|
|
73732
73604
|
return `View agent: \x1B]8;;${url}\x1B\\${agentId}\x1B]8;;\x1B\\ (run: ${runId})`;
|
|
73733
73605
|
}
|
|
73734
|
-
var LETTA_USAGE_URL2, LETTA_AGENTS_URL2, CLOUDFLARE_EDGE_5XX_MARKER_PATTERN2, CLOUDFLARE_EDGE_5XX_TITLE_PATTERN2, CHATGPT_USAGE_LIMIT_HINT2 = "Switch models with /model, or connect your own provider keys with /connect.", ENCRYPTED_CONTENT_HINT2, DEFAULT_RETRY_MESSAGE = "Unexpected downstream LLM API error, retrying...", ENDPOINT_TYPE_DISPLAY_NAMES;
|
|
73606
|
+
var LETTA_USAGE_URL2, LETTA_AGENTS_URL2, CLOUDFLARE_EDGE_5XX_MARKER_PATTERN2, CLOUDFLARE_EDGE_5XX_TITLE_PATTERN2, CLOUDFLARE_EDGE_5XX_FORMATTED_PATTERN, CHATGPT_USAGE_LIMIT_HINT2 = "Switch models with /model, or connect your own provider keys with /connect.", ENCRYPTED_CONTENT_HINT2, DEFAULT_RETRY_MESSAGE = "Unexpected downstream LLM API error, retrying...", ENDPOINT_TYPE_DISPLAY_NAMES;
|
|
73735
73607
|
var init_errorFormatter = __esm(() => {
|
|
73736
73608
|
init_error();
|
|
73737
73609
|
init_errorContext();
|
|
@@ -73740,6 +73612,7 @@ var init_errorFormatter = __esm(() => {
|
|
|
73740
73612
|
LETTA_AGENTS_URL2 = buildAppUrl("/projects/default-project/agents");
|
|
73741
73613
|
CLOUDFLARE_EDGE_5XX_MARKER_PATTERN2 = /(^|\s)(502|52[0-6])\s*<!doctype html|error code\s*(502|52[0-6])/i;
|
|
73742
73614
|
CLOUDFLARE_EDGE_5XX_TITLE_PATTERN2 = /\|\s*(502|52[0-6])\s*:/i;
|
|
73615
|
+
CLOUDFLARE_EDGE_5XX_FORMATTED_PATTERN = /\bCloudflare\s+(502|52[0-6])\b/i;
|
|
73743
73616
|
ENCRYPTED_CONTENT_HINT2 = [
|
|
73744
73617
|
"",
|
|
73745
73618
|
"This occurs when the conversation contains messages with encrypted",
|
|
@@ -73766,7 +73639,7 @@ import { randomUUID as randomUUID3 } from "node:crypto";
|
|
|
73766
73639
|
function isCloudflareEdge52xDetail(detail) {
|
|
73767
73640
|
if (typeof detail !== "string")
|
|
73768
73641
|
return false;
|
|
73769
|
-
return
|
|
73642
|
+
return isCloudflareEdge52xErrorText(detail);
|
|
73770
73643
|
}
|
|
73771
73644
|
function isQuotaLimitErrorDetail(detail) {
|
|
73772
73645
|
return hasNonRetryableQuotaDetail(detail);
|
|
@@ -74512,7 +74385,7 @@ var init_approval_result_normalization = __esm(() => {
|
|
|
74512
74385
|
});
|
|
74513
74386
|
|
|
74514
74387
|
// src/agent/clientSkills.ts
|
|
74515
|
-
import { join as
|
|
74388
|
+
import { join as join23 } from "node:path";
|
|
74516
74389
|
function toClientSkill(skill2) {
|
|
74517
74390
|
return {
|
|
74518
74391
|
name: skill2.id,
|
|
@@ -74521,12 +74394,12 @@ function toClientSkill(skill2) {
|
|
|
74521
74394
|
};
|
|
74522
74395
|
}
|
|
74523
74396
|
function resolveSkillDiscoveryContext(options) {
|
|
74524
|
-
const legacySkillsDirectory = options.skillsDirectory ?? getSkillsDirectory() ??
|
|
74397
|
+
const legacySkillsDirectory = options.skillsDirectory ?? getSkillsDirectory() ?? join23(process.cwd(), SKILLS_DIR);
|
|
74525
74398
|
const skillSources = options.skillSources ?? getSkillSources();
|
|
74526
74399
|
return { legacySkillsDirectory, skillSources };
|
|
74527
74400
|
}
|
|
74528
74401
|
function getPrimaryProjectSkillsDirectory() {
|
|
74529
|
-
return
|
|
74402
|
+
return join23(process.cwd(), ".agents", "skills");
|
|
74530
74403
|
}
|
|
74531
74404
|
async function buildClientSkillsPayload(options = {}) {
|
|
74532
74405
|
const { legacySkillsDirectory, skillSources } = resolveSkillDiscoveryContext(options);
|
|
@@ -75975,7 +75848,7 @@ import {
|
|
|
75975
75848
|
writeFile as writeFile4
|
|
75976
75849
|
} from "node:fs/promises";
|
|
75977
75850
|
import { homedir as homedir20, tmpdir as tmpdir3 } from "node:os";
|
|
75978
|
-
import { join as
|
|
75851
|
+
import { join as join24 } from "node:path";
|
|
75979
75852
|
function buildReflectionSubagentPrompt(input) {
|
|
75980
75853
|
const lines = [];
|
|
75981
75854
|
if (input.cwd) {
|
|
@@ -76008,7 +75881,7 @@ async function collectParentMemoryFiles(memoryDir) {
|
|
|
76008
75881
|
return a.name.localeCompare(b.name);
|
|
76009
75882
|
});
|
|
76010
75883
|
for (const entry of sortedEntries) {
|
|
76011
|
-
const entryPath =
|
|
75884
|
+
const entryPath = join24(currentDir, entry.name);
|
|
76012
75885
|
const relativePath = relativeDir ? `${relativeDir}/${entry.name}` : entry.name;
|
|
76013
75886
|
if (entry.isDirectory()) {
|
|
76014
75887
|
await walk(entryPath, relativePath);
|
|
@@ -76168,7 +76041,7 @@ function getTranscriptRoot() {
|
|
|
76168
76041
|
if (envRoot) {
|
|
76169
76042
|
return envRoot;
|
|
76170
76043
|
}
|
|
76171
|
-
return
|
|
76044
|
+
return join24(homedir20(), ".letta", DEFAULT_TRANSCRIPT_DIR);
|
|
76172
76045
|
}
|
|
76173
76046
|
function defaultState() {
|
|
76174
76047
|
return { auto_cursor_line: 0 };
|
|
@@ -76280,14 +76153,14 @@ async function readTranscriptLines(paths) {
|
|
|
76280
76153
|
}
|
|
76281
76154
|
function buildPayloadPath(kind) {
|
|
76282
76155
|
const nonce = Math.random().toString(36).slice(2, 8);
|
|
76283
|
-
return
|
|
76156
|
+
return join24(tmpdir3(), `letta-${kind}-${nonce}.txt`);
|
|
76284
76157
|
}
|
|
76285
76158
|
function getReflectionTranscriptPaths(agentId, conversationId) {
|
|
76286
|
-
const rootDir =
|
|
76159
|
+
const rootDir = join24(getTranscriptRoot(), sanitizePathSegment(agentId), sanitizePathSegment(conversationId));
|
|
76287
76160
|
return {
|
|
76288
76161
|
rootDir,
|
|
76289
|
-
transcriptPath:
|
|
76290
|
-
statePath:
|
|
76162
|
+
transcriptPath: join24(rootDir, "transcript.jsonl"),
|
|
76163
|
+
statePath: join24(rootDir, "state.json")
|
|
76291
76164
|
};
|
|
76292
76165
|
}
|
|
76293
76166
|
async function appendTranscriptDeltaJsonl(agentId, conversationId, lines) {
|
|
@@ -76351,14 +76224,14 @@ var init_reflectionTranscript = __esm(async () => {
|
|
|
76351
76224
|
|
|
76352
76225
|
// src/cli/helpers/chunkLog.ts
|
|
76353
76226
|
import {
|
|
76354
|
-
existsSync as
|
|
76227
|
+
existsSync as existsSync19,
|
|
76355
76228
|
mkdirSync as mkdirSync14,
|
|
76356
|
-
readdirSync as
|
|
76229
|
+
readdirSync as readdirSync8,
|
|
76357
76230
|
unlinkSync as unlinkSync7,
|
|
76358
76231
|
writeFileSync as writeFileSync11
|
|
76359
76232
|
} from "node:fs";
|
|
76360
76233
|
import { homedir as homedir21 } from "node:os";
|
|
76361
|
-
import { join as
|
|
76234
|
+
import { join as join25 } from "node:path";
|
|
76362
76235
|
function truncateStr(value, maxLen) {
|
|
76363
76236
|
if (value === null || value === undefined)
|
|
76364
76237
|
return "";
|
|
@@ -76422,8 +76295,8 @@ class ChunkLog {
|
|
|
76422
76295
|
agentDir = null;
|
|
76423
76296
|
dirCreated = false;
|
|
76424
76297
|
init(agentId, sessionId) {
|
|
76425
|
-
this.agentDir =
|
|
76426
|
-
this.logPath =
|
|
76298
|
+
this.agentDir = join25(LOG_BASE_DIR, agentId);
|
|
76299
|
+
this.logPath = join25(this.agentDir, `${sessionId}.jsonl`);
|
|
76427
76300
|
this.buffer = [];
|
|
76428
76301
|
this.dirty = false;
|
|
76429
76302
|
this.dirCreated = false;
|
|
@@ -76452,7 +76325,7 @@ class ChunkLog {
|
|
|
76452
76325
|
if (this.dirCreated || !this.agentDir)
|
|
76453
76326
|
return;
|
|
76454
76327
|
try {
|
|
76455
|
-
if (!
|
|
76328
|
+
if (!existsSync19(this.agentDir)) {
|
|
76456
76329
|
mkdirSync14(this.agentDir, { recursive: true });
|
|
76457
76330
|
}
|
|
76458
76331
|
this.dirCreated = true;
|
|
@@ -76477,14 +76350,14 @@ class ChunkLog {
|
|
|
76477
76350
|
if (!this.agentDir)
|
|
76478
76351
|
return;
|
|
76479
76352
|
try {
|
|
76480
|
-
if (!
|
|
76353
|
+
if (!existsSync19(this.agentDir))
|
|
76481
76354
|
return;
|
|
76482
|
-
const files =
|
|
76355
|
+
const files = readdirSync8(this.agentDir).filter((f) => f.endsWith(".jsonl")).sort();
|
|
76483
76356
|
if (files.length >= MAX_SESSION_FILES2) {
|
|
76484
76357
|
const toDelete = files.slice(0, files.length - MAX_SESSION_FILES2 + 1);
|
|
76485
76358
|
for (const file of toDelete) {
|
|
76486
76359
|
try {
|
|
76487
|
-
unlinkSync7(
|
|
76360
|
+
unlinkSync7(join25(this.agentDir, file));
|
|
76488
76361
|
} catch (e) {
|
|
76489
76362
|
debugWarn("chunkLog", `Failed to delete old session log ${file}: ${e instanceof Error ? e.message : String(e)}`);
|
|
76490
76363
|
}
|
|
@@ -76498,7 +76371,7 @@ class ChunkLog {
|
|
|
76498
76371
|
var MAX_ENTRIES = 100, CONTENT_TRUNCATE_LEN = 200, MAX_SESSION_FILES2 = 5, LOG_BASE_DIR, chunkLog;
|
|
76499
76372
|
var init_chunkLog = __esm(() => {
|
|
76500
76373
|
init_debug();
|
|
76501
|
-
LOG_BASE_DIR =
|
|
76374
|
+
LOG_BASE_DIR = join25(homedir21(), ".letta", "logs", "chunk-logs");
|
|
76502
76375
|
chunkLog = new ChunkLog;
|
|
76503
76376
|
});
|
|
76504
76377
|
|
|
@@ -77245,11 +77118,6 @@ var init_catalog = __esm(() => {
|
|
|
77245
77118
|
id: "toolset-change",
|
|
77246
77119
|
description: "Client-side toolset change context",
|
|
77247
77120
|
modes: ["interactive"]
|
|
77248
|
-
},
|
|
77249
|
-
{
|
|
77250
|
-
id: "auto-init",
|
|
77251
|
-
description: "Auto-init background onboarding notification",
|
|
77252
|
-
modes: ["interactive"]
|
|
77253
77121
|
}
|
|
77254
77122
|
];
|
|
77255
77123
|
SHARED_REMINDER_IDS = SHARED_REMINDER_CATALOG.map((entry) => entry.id);
|
|
@@ -77381,13 +77249,6 @@ async function buildReflectionCompactionReminder(context3) {
|
|
|
77381
77249
|
}
|
|
77382
77250
|
return buildCompactionMemoryReminder(context3.agent.id);
|
|
77383
77251
|
}
|
|
77384
|
-
async function buildAutoInitReminder(context3) {
|
|
77385
|
-
if (!context3.state.pendingAutoInitReminder)
|
|
77386
|
-
return null;
|
|
77387
|
-
context3.state.pendingAutoInitReminder = false;
|
|
77388
|
-
const { AUTO_INIT_REMINDER: AUTO_INIT_REMINDER2 } = await Promise.resolve().then(() => (init_promptAssets(), exports_promptAssets));
|
|
77389
|
-
return AUTO_INIT_REMINDER2;
|
|
77390
|
-
}
|
|
77391
77252
|
function escapeXml2(value) {
|
|
77392
77253
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
77393
77254
|
}
|
|
@@ -77537,8 +77398,7 @@ var init_engine = __esm(async () => {
|
|
|
77537
77398
|
"reflection-step-count": buildReflectionStepReminder,
|
|
77538
77399
|
"reflection-compaction": buildReflectionCompactionReminder,
|
|
77539
77400
|
"command-io": buildCommandIoReminder,
|
|
77540
|
-
"toolset-change": buildToolsetChangeReminder
|
|
77541
|
-
"auto-init": buildAutoInitReminder
|
|
77401
|
+
"toolset-change": buildToolsetChangeReminder
|
|
77542
77402
|
};
|
|
77543
77403
|
assertSharedReminderCoverage();
|
|
77544
77404
|
});
|
|
@@ -77636,7 +77496,7 @@ var init_constants2 = __esm(() => {
|
|
|
77636
77496
|
});
|
|
77637
77497
|
|
|
77638
77498
|
// src/websocket/listener/remote-settings.ts
|
|
77639
|
-
import { existsSync as
|
|
77499
|
+
import { existsSync as existsSync20, readFileSync as readFileSync11 } from "node:fs";
|
|
77640
77500
|
import { mkdir as mkdir5, writeFile as writeFile5 } from "node:fs/promises";
|
|
77641
77501
|
import { homedir as homedir22 } from "node:os";
|
|
77642
77502
|
import path20 from "node:path";
|
|
@@ -77650,8 +77510,8 @@ function loadRemoteSettings() {
|
|
|
77650
77510
|
let loaded = {};
|
|
77651
77511
|
try {
|
|
77652
77512
|
const settingsPath = getRemoteSettingsPath();
|
|
77653
|
-
if (
|
|
77654
|
-
const raw =
|
|
77513
|
+
if (existsSync20(settingsPath)) {
|
|
77514
|
+
const raw = readFileSync11(settingsPath, "utf-8");
|
|
77655
77515
|
const parsed = JSON.parse(raw);
|
|
77656
77516
|
loaded = parsed;
|
|
77657
77517
|
}
|
|
@@ -77659,7 +77519,7 @@ function loadRemoteSettings() {
|
|
|
77659
77519
|
if (loaded.cwdMap) {
|
|
77660
77520
|
const validCwdMap = {};
|
|
77661
77521
|
for (const [key, value] of Object.entries(loaded.cwdMap)) {
|
|
77662
|
-
if (typeof value === "string" &&
|
|
77522
|
+
if (typeof value === "string" && existsSync20(value)) {
|
|
77663
77523
|
validCwdMap[key] = value;
|
|
77664
77524
|
}
|
|
77665
77525
|
}
|
|
@@ -77686,13 +77546,13 @@ function saveRemoteSettings(updates) {
|
|
|
77686
77546
|
function loadLegacyCwdCache() {
|
|
77687
77547
|
try {
|
|
77688
77548
|
const legacyPath = path20.join(homedir22(), ".letta", "cwd-cache.json");
|
|
77689
|
-
if (!
|
|
77549
|
+
if (!existsSync20(legacyPath))
|
|
77690
77550
|
return {};
|
|
77691
|
-
const raw =
|
|
77551
|
+
const raw = readFileSync11(legacyPath, "utf-8");
|
|
77692
77552
|
const parsed = JSON.parse(raw);
|
|
77693
77553
|
const result = {};
|
|
77694
77554
|
for (const [key, value] of Object.entries(parsed)) {
|
|
77695
|
-
if (typeof value === "string" &&
|
|
77555
|
+
if (typeof value === "string" && existsSync20(value)) {
|
|
77696
77556
|
result[key] = value;
|
|
77697
77557
|
}
|
|
77698
77558
|
}
|
|
@@ -80106,7 +79966,7 @@ function shouldAttemptPostStopApprovalRecovery(params) {
|
|
|
80106
79966
|
maxRetries: MAX_POST_STOP_APPROVAL_RECOVERY
|
|
80107
79967
|
});
|
|
80108
79968
|
}
|
|
80109
|
-
async function isRetriablePostStopError(stopReason, lastRunId) {
|
|
79969
|
+
async function isRetriablePostStopError(stopReason, lastRunId, fallbackDetail) {
|
|
80110
79970
|
if (stopReason === "llm_api_error") {
|
|
80111
79971
|
return true;
|
|
80112
79972
|
}
|
|
@@ -80124,7 +79984,7 @@ async function isRetriablePostStopError(stopReason, lastRunId) {
|
|
|
80124
79984
|
return false;
|
|
80125
79985
|
}
|
|
80126
79986
|
if (!lastRunId) {
|
|
80127
|
-
return
|
|
79987
|
+
return shouldRetryRunMetadataError(undefined, fallbackDetail);
|
|
80128
79988
|
}
|
|
80129
79989
|
try {
|
|
80130
79990
|
const client = await getClient();
|
|
@@ -80134,7 +79994,7 @@ async function isRetriablePostStopError(stopReason, lastRunId) {
|
|
|
80134
79994
|
const detail = metaError?.detail ?? metaError?.error?.detail ?? "";
|
|
80135
79995
|
return shouldRetryRunMetadataError(errorType, detail);
|
|
80136
79996
|
} catch {
|
|
80137
|
-
return
|
|
79997
|
+
return shouldRetryRunMetadataError(undefined, fallbackDetail);
|
|
80138
79998
|
}
|
|
80139
79999
|
}
|
|
80140
80000
|
async function drainRecoveryStreamWithEmission(recoveryStream, socket, runtime, params) {
|
|
@@ -81931,7 +81791,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
|
|
|
81931
81791
|
turnToolContextId = getStreamToolContextId(stream2);
|
|
81932
81792
|
continue;
|
|
81933
81793
|
}
|
|
81934
|
-
const retriable = await isRetriablePostStopError(stopReason || "error", lastRunId);
|
|
81794
|
+
const retriable = await isRetriablePostStopError(stopReason || "error", lastRunId, errorDetail);
|
|
81935
81795
|
if (retriable && llmApiErrorRetries < LLM_API_ERROR_MAX_RETRIES) {
|
|
81936
81796
|
llmApiErrorRetries += 1;
|
|
81937
81797
|
const attempt = llmApiErrorRetries;
|
|
@@ -82323,11 +82183,11 @@ var init_commands = __esm(async () => {
|
|
|
82323
82183
|
init_memory();
|
|
82324
82184
|
init_memoryFilesystem();
|
|
82325
82185
|
init_promptAssets();
|
|
82186
|
+
init_initCommand();
|
|
82326
82187
|
init_constants();
|
|
82327
82188
|
init_runtime();
|
|
82328
82189
|
await __promiseAll([
|
|
82329
82190
|
init_client2(),
|
|
82330
|
-
init_initCommand(),
|
|
82331
82191
|
init_settings_manager(),
|
|
82332
82192
|
init_errorReporting(),
|
|
82333
82193
|
init_protocol_outbound(),
|
|
@@ -83670,6 +83530,18 @@ function isListMemoryCommand(value) {
|
|
|
83670
83530
|
const c = value;
|
|
83671
83531
|
return c.type === "list_memory" && typeof c.request_id === "string" && typeof c.agent_id === "string";
|
|
83672
83532
|
}
|
|
83533
|
+
function isMemoryHistoryCommand(value) {
|
|
83534
|
+
if (!value || typeof value !== "object")
|
|
83535
|
+
return false;
|
|
83536
|
+
const c = value;
|
|
83537
|
+
return c.type === "memory_history" && typeof c.request_id === "string" && typeof c.agent_id === "string" && typeof c.file_path === "string";
|
|
83538
|
+
}
|
|
83539
|
+
function isMemoryFileAtRefCommand(value) {
|
|
83540
|
+
if (!value || typeof value !== "object")
|
|
83541
|
+
return false;
|
|
83542
|
+
const c = value;
|
|
83543
|
+
return c.type === "memory_file_at_ref" && typeof c.request_id === "string" && typeof c.agent_id === "string" && typeof c.file_path === "string" && typeof c.ref === "string";
|
|
83544
|
+
}
|
|
83673
83545
|
function isEnableMemfsCommand(value) {
|
|
83674
83546
|
if (!value || typeof value !== "object")
|
|
83675
83547
|
return false;
|
|
@@ -83782,7 +83654,7 @@ function parseServerMessage(data) {
|
|
|
83782
83654
|
try {
|
|
83783
83655
|
const raw = typeof data === "string" ? data : data.toString();
|
|
83784
83656
|
const parsed = JSON.parse(raw);
|
|
83785
|
-
if (isInputCommand(parsed) || isChangeDeviceStateCommand(parsed) || isAbortMessageCommand(parsed) || isSyncCommand(parsed) || isTerminalSpawnCommand(parsed) || isTerminalInputCommand(parsed) || isTerminalResizeCommand(parsed) || isTerminalKillCommand(parsed) || isSearchFilesCommand(parsed) || isListInDirectoryCommand(parsed) || isReadFileCommand(parsed) || isWriteFileCommand(parsed) || isEditFileCommand(parsed) || isListMemoryCommand(parsed) || isEnableMemfsCommand(parsed) || isListModelsCommand(parsed) || isUpdateModelCommand(parsed) || isCronListCommand(parsed) || isCronAddCommand(parsed) || isCronGetCommand(parsed) || isCronDeleteCommand(parsed) || isCronDeleteAllCommand(parsed) || isSkillEnableCommand(parsed) || isSkillDisableCommand(parsed) || isCreateAgentCommand(parsed) || isGetReflectionSettingsCommand(parsed) || isSetReflectionSettingsCommand(parsed) || isExecuteCommandCommand(parsed) || isSearchBranchesCommand(parsed) || isCheckoutBranchCommand(parsed)) {
|
|
83657
|
+
if (isInputCommand(parsed) || isChangeDeviceStateCommand(parsed) || isAbortMessageCommand(parsed) || isSyncCommand(parsed) || isTerminalSpawnCommand(parsed) || isTerminalInputCommand(parsed) || isTerminalResizeCommand(parsed) || isTerminalKillCommand(parsed) || isSearchFilesCommand(parsed) || isListInDirectoryCommand(parsed) || isReadFileCommand(parsed) || isWriteFileCommand(parsed) || isEditFileCommand(parsed) || isListMemoryCommand(parsed) || isMemoryHistoryCommand(parsed) || isMemoryFileAtRefCommand(parsed) || isEnableMemfsCommand(parsed) || isListModelsCommand(parsed) || isUpdateModelCommand(parsed) || isCronListCommand(parsed) || isCronAddCommand(parsed) || isCronGetCommand(parsed) || isCronDeleteCommand(parsed) || isCronDeleteAllCommand(parsed) || isSkillEnableCommand(parsed) || isSkillDisableCommand(parsed) || isCreateAgentCommand(parsed) || isGetReflectionSettingsCommand(parsed) || isSetReflectionSettingsCommand(parsed) || isExecuteCommandCommand(parsed) || isSearchBranchesCommand(parsed) || isCheckoutBranchCommand(parsed)) {
|
|
83786
83658
|
return parsed;
|
|
83787
83659
|
}
|
|
83788
83660
|
const invalidInput = getInvalidInputReason(parsed);
|
|
@@ -83810,21 +83682,21 @@ __export(exports_memoryScanner, {
|
|
|
83810
83682
|
readFileContent: () => readFileContent,
|
|
83811
83683
|
getFileNodes: () => getFileNodes
|
|
83812
83684
|
});
|
|
83813
|
-
import { readdirSync as
|
|
83814
|
-
import { join as
|
|
83685
|
+
import { readdirSync as readdirSync9, readFileSync as readFileSync12, statSync as statSync7 } from "node:fs";
|
|
83686
|
+
import { join as join26, relative as relative11 } from "node:path";
|
|
83815
83687
|
function scanMemoryFilesystem(memoryRoot) {
|
|
83816
83688
|
const nodes = [];
|
|
83817
83689
|
const scanDir = (dir, depth, parentIsLast) => {
|
|
83818
83690
|
let entries;
|
|
83819
83691
|
try {
|
|
83820
|
-
entries =
|
|
83692
|
+
entries = readdirSync9(dir);
|
|
83821
83693
|
} catch {
|
|
83822
83694
|
return;
|
|
83823
83695
|
}
|
|
83824
83696
|
const filtered = entries.filter((name) => !name.startsWith("."));
|
|
83825
83697
|
const sorted = filtered.sort((a, b) => {
|
|
83826
|
-
const aPath =
|
|
83827
|
-
const bPath =
|
|
83698
|
+
const aPath = join26(dir, a);
|
|
83699
|
+
const bPath = join26(dir, b);
|
|
83828
83700
|
let aIsDir = false;
|
|
83829
83701
|
let bIsDir = false;
|
|
83830
83702
|
try {
|
|
@@ -83844,7 +83716,7 @@ function scanMemoryFilesystem(memoryRoot) {
|
|
|
83844
83716
|
return a.localeCompare(b);
|
|
83845
83717
|
});
|
|
83846
83718
|
sorted.forEach((name, index) => {
|
|
83847
|
-
const fullPath =
|
|
83719
|
+
const fullPath = join26(dir, name);
|
|
83848
83720
|
let isDir = false;
|
|
83849
83721
|
try {
|
|
83850
83722
|
isDir = statSync7(fullPath).isDirectory();
|
|
@@ -83875,7 +83747,7 @@ function getFileNodes(nodes) {
|
|
|
83875
83747
|
}
|
|
83876
83748
|
function readFileContent(fullPath) {
|
|
83877
83749
|
try {
|
|
83878
|
-
return
|
|
83750
|
+
return readFileSync12(fullPath, "utf-8");
|
|
83879
83751
|
} catch {
|
|
83880
83752
|
return "(unable to read file)";
|
|
83881
83753
|
}
|
|
@@ -84321,19 +84193,19 @@ function emitSkillsUpdated(socket) {
|
|
|
84321
84193
|
}
|
|
84322
84194
|
async function handleSkillCommand(parsed, socket) {
|
|
84323
84195
|
const {
|
|
84324
|
-
existsSync:
|
|
84196
|
+
existsSync: existsSync21,
|
|
84325
84197
|
lstatSync: lstatSync2,
|
|
84326
84198
|
mkdirSync: mkdirSync15,
|
|
84327
84199
|
rmdirSync,
|
|
84328
84200
|
symlinkSync,
|
|
84329
84201
|
unlinkSync: unlinkSync8
|
|
84330
84202
|
} = await import("node:fs");
|
|
84331
|
-
const { basename: basename5, join:
|
|
84332
|
-
const lettaHome = process.env.LETTA_HOME ||
|
|
84333
|
-
const globalSkillsDir =
|
|
84203
|
+
const { basename: basename5, join: join27 } = await import("node:path");
|
|
84204
|
+
const lettaHome = process.env.LETTA_HOME || join27(process.env.HOME || process.env.USERPROFILE || "~", ".letta");
|
|
84205
|
+
const globalSkillsDir = join27(lettaHome, "skills");
|
|
84334
84206
|
if (parsed.type === "skill_enable") {
|
|
84335
84207
|
try {
|
|
84336
|
-
if (!
|
|
84208
|
+
if (!existsSync21(parsed.skill_path)) {
|
|
84337
84209
|
safeSocketSend(socket, {
|
|
84338
84210
|
type: "skill_enable_response",
|
|
84339
84211
|
request_id: parsed.request_id,
|
|
@@ -84342,8 +84214,8 @@ async function handleSkillCommand(parsed, socket) {
|
|
|
84342
84214
|
}, "listener_skill_send_failed", "listener_skill_command");
|
|
84343
84215
|
return true;
|
|
84344
84216
|
}
|
|
84345
|
-
const skillMdPath =
|
|
84346
|
-
if (!
|
|
84217
|
+
const skillMdPath = join27(parsed.skill_path, "SKILL.md");
|
|
84218
|
+
if (!existsSync21(skillMdPath)) {
|
|
84347
84219
|
safeSocketSend(socket, {
|
|
84348
84220
|
type: "skill_enable_response",
|
|
84349
84221
|
request_id: parsed.request_id,
|
|
@@ -84353,9 +84225,9 @@ async function handleSkillCommand(parsed, socket) {
|
|
|
84353
84225
|
return true;
|
|
84354
84226
|
}
|
|
84355
84227
|
const linkName = basename5(parsed.skill_path);
|
|
84356
|
-
const linkPath =
|
|
84228
|
+
const linkPath = join27(globalSkillsDir, linkName);
|
|
84357
84229
|
mkdirSync15(globalSkillsDir, { recursive: true });
|
|
84358
|
-
if (
|
|
84230
|
+
if (existsSync21(linkPath)) {
|
|
84359
84231
|
const stat6 = lstatSync2(linkPath);
|
|
84360
84232
|
if (stat6.isSymbolicLink()) {
|
|
84361
84233
|
if (process.platform === "win32") {
|
|
@@ -84396,8 +84268,8 @@ async function handleSkillCommand(parsed, socket) {
|
|
|
84396
84268
|
}
|
|
84397
84269
|
if (parsed.type === "skill_disable") {
|
|
84398
84270
|
try {
|
|
84399
|
-
const linkPath =
|
|
84400
|
-
if (!
|
|
84271
|
+
const linkPath = join27(globalSkillsDir, parsed.name);
|
|
84272
|
+
if (!existsSync21(linkPath)) {
|
|
84401
84273
|
safeSocketSend(socket, {
|
|
84402
84274
|
type: "skill_disable_response",
|
|
84403
84275
|
request_id: parsed.request_id,
|
|
@@ -85377,10 +85249,10 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
85377
85249
|
const { getMemoryFilesystemRoot: getMemoryFilesystemRoot2 } = await Promise.resolve().then(() => (init_memoryFilesystem(), exports_memoryFilesystem));
|
|
85378
85250
|
const { scanMemoryFilesystem: scanMemoryFilesystem2, getFileNodes: getFileNodes2, readFileContent: readFileContent2 } = await Promise.resolve().then(() => (init_memoryScanner(), exports_memoryScanner));
|
|
85379
85251
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => exports_frontmatter);
|
|
85380
|
-
const { existsSync:
|
|
85381
|
-
const { join:
|
|
85252
|
+
const { existsSync: existsSync21 } = await import("node:fs");
|
|
85253
|
+
const { join: join27 } = await import("node:path");
|
|
85382
85254
|
const memoryRoot = getMemoryFilesystemRoot2(parsed.agent_id);
|
|
85383
|
-
const memfsInitialized =
|
|
85255
|
+
const memfsInitialized = existsSync21(join27(memoryRoot, ".git"));
|
|
85384
85256
|
if (!memfsInitialized) {
|
|
85385
85257
|
safeSocketSend(socket, {
|
|
85386
85258
|
type: "list_memory_response",
|
|
@@ -85537,6 +85409,72 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
85537
85409
|
});
|
|
85538
85410
|
return;
|
|
85539
85411
|
}
|
|
85412
|
+
if (isMemoryHistoryCommand(parsed)) {
|
|
85413
|
+
runDetachedListenerTask("memory_history", async () => {
|
|
85414
|
+
const { getMemoryFilesystemRoot: getMemoryFilesystemRoot2 } = await Promise.resolve().then(() => (init_memoryFilesystem(), exports_memoryFilesystem));
|
|
85415
|
+
const { execFile: execFileCb5 } = await import("node:child_process");
|
|
85416
|
+
const { promisify: promisify13 } = await import("node:util");
|
|
85417
|
+
const execFileAsync7 = promisify13(execFileCb5);
|
|
85418
|
+
const memoryRoot = getMemoryFilesystemRoot2(parsed.agent_id);
|
|
85419
|
+
const limit2 = parsed.limit ?? 50;
|
|
85420
|
+
const { stdout } = await execFileAsync7("git", [
|
|
85421
|
+
"log",
|
|
85422
|
+
`--max-count=${limit2}`,
|
|
85423
|
+
"--format=%H|%s|%aI|%an",
|
|
85424
|
+
"--",
|
|
85425
|
+
parsed.file_path
|
|
85426
|
+
], { cwd: memoryRoot, timeout: 1e4 });
|
|
85427
|
+
const commits = stdout.trim().split(`
|
|
85428
|
+
`).filter((line) => line.length > 0).map((line) => {
|
|
85429
|
+
const [sha, message, timestamp, authorName] = line.split("|");
|
|
85430
|
+
return {
|
|
85431
|
+
sha: sha ?? "",
|
|
85432
|
+
message: message ?? "",
|
|
85433
|
+
timestamp: timestamp ?? "",
|
|
85434
|
+
author_name: authorName ?? null
|
|
85435
|
+
};
|
|
85436
|
+
});
|
|
85437
|
+
safeSocketSend(socket, {
|
|
85438
|
+
type: "memory_history_response",
|
|
85439
|
+
request_id: parsed.request_id,
|
|
85440
|
+
file_path: parsed.file_path,
|
|
85441
|
+
commits,
|
|
85442
|
+
success: true
|
|
85443
|
+
}, "listener_memory_history_send_failed", "listener_memory_history");
|
|
85444
|
+
});
|
|
85445
|
+
return;
|
|
85446
|
+
}
|
|
85447
|
+
if (isMemoryFileAtRefCommand(parsed)) {
|
|
85448
|
+
runDetachedListenerTask("memory_file_at_ref", async () => {
|
|
85449
|
+
const { getMemoryFilesystemRoot: getMemoryFilesystemRoot2 } = await Promise.resolve().then(() => (init_memoryFilesystem(), exports_memoryFilesystem));
|
|
85450
|
+
const { execFile: execFileCb5 } = await import("node:child_process");
|
|
85451
|
+
const { promisify: promisify13 } = await import("node:util");
|
|
85452
|
+
const execFileAsync7 = promisify13(execFileCb5);
|
|
85453
|
+
const memoryRoot = getMemoryFilesystemRoot2(parsed.agent_id);
|
|
85454
|
+
try {
|
|
85455
|
+
const { stdout } = await execFileAsync7("git", ["show", `${parsed.ref}:${parsed.file_path}`], { cwd: memoryRoot, timeout: 1e4 });
|
|
85456
|
+
safeSocketSend(socket, {
|
|
85457
|
+
type: "memory_file_at_ref_response",
|
|
85458
|
+
request_id: parsed.request_id,
|
|
85459
|
+
file_path: parsed.file_path,
|
|
85460
|
+
ref: parsed.ref,
|
|
85461
|
+
content: stdout,
|
|
85462
|
+
success: true
|
|
85463
|
+
}, "listener_memory_file_at_ref_send_failed", "listener_memory_file_at_ref");
|
|
85464
|
+
} catch (err) {
|
|
85465
|
+
safeSocketSend(socket, {
|
|
85466
|
+
type: "memory_file_at_ref_response",
|
|
85467
|
+
request_id: parsed.request_id,
|
|
85468
|
+
file_path: parsed.file_path,
|
|
85469
|
+
ref: parsed.ref,
|
|
85470
|
+
content: null,
|
|
85471
|
+
success: false,
|
|
85472
|
+
error: err instanceof Error ? err.message : "Failed to read file at ref"
|
|
85473
|
+
}, "listener_memory_file_at_ref_send_failed", "listener_memory_file_at_ref");
|
|
85474
|
+
}
|
|
85475
|
+
});
|
|
85476
|
+
return;
|
|
85477
|
+
}
|
|
85540
85478
|
if (isCronListCommand(parsed) || isCronAddCommand(parsed) || isCronGetCommand(parsed) || isCronDeleteCommand(parsed) || isCronDeleteAllCommand(parsed)) {
|
|
85541
85479
|
runDetachedListenerTask("cron_command", async () => {
|
|
85542
85480
|
await handleCronCommand(parsed, socket);
|
|
@@ -86066,14 +86004,14 @@ __export(exports_debug2, {
|
|
|
86066
86004
|
});
|
|
86067
86005
|
import {
|
|
86068
86006
|
appendFileSync as appendFileSync3,
|
|
86069
|
-
existsSync as
|
|
86007
|
+
existsSync as existsSync22,
|
|
86070
86008
|
mkdirSync as mkdirSync16,
|
|
86071
|
-
readdirSync as
|
|
86072
|
-
readFileSync as
|
|
86009
|
+
readdirSync as readdirSync10,
|
|
86010
|
+
readFileSync as readFileSync13,
|
|
86073
86011
|
unlinkSync as unlinkSync8
|
|
86074
86012
|
} from "node:fs";
|
|
86075
86013
|
import { homedir as homedir26 } from "node:os";
|
|
86076
|
-
import { join as
|
|
86014
|
+
import { join as join30 } from "node:path";
|
|
86077
86015
|
import { format as format2 } from "node:util";
|
|
86078
86016
|
function isDebugEnabled2() {
|
|
86079
86017
|
const lettaDebug = process.env.LETTA_DEBUG;
|
|
@@ -86104,8 +86042,8 @@ class DebugLogFile2 {
|
|
|
86104
86042
|
const telem = process.env.LETTA_CODE_TELEM;
|
|
86105
86043
|
if (telem === "0" || telem === "false")
|
|
86106
86044
|
return;
|
|
86107
|
-
this.agentDir =
|
|
86108
|
-
this.logPath =
|
|
86045
|
+
this.agentDir = join30(DEBUG_LOG_DIR2, agentId);
|
|
86046
|
+
this.logPath = join30(this.agentDir, `${sessionId}.log`);
|
|
86109
86047
|
this.dirCreated = false;
|
|
86110
86048
|
this.pruneOldSessions();
|
|
86111
86049
|
}
|
|
@@ -86121,9 +86059,9 @@ class DebugLogFile2 {
|
|
|
86121
86059
|
if (!this.logPath)
|
|
86122
86060
|
return;
|
|
86123
86061
|
try {
|
|
86124
|
-
if (!
|
|
86062
|
+
if (!existsSync22(this.logPath))
|
|
86125
86063
|
return;
|
|
86126
|
-
const content =
|
|
86064
|
+
const content = readFileSync13(this.logPath, "utf8");
|
|
86127
86065
|
const lines = content.trimEnd().split(`
|
|
86128
86066
|
`);
|
|
86129
86067
|
return lines.slice(-maxLines).join(`
|
|
@@ -86136,7 +86074,7 @@ class DebugLogFile2 {
|
|
|
86136
86074
|
if (this.dirCreated || !this.agentDir)
|
|
86137
86075
|
return;
|
|
86138
86076
|
try {
|
|
86139
|
-
if (!
|
|
86077
|
+
if (!existsSync22(this.agentDir)) {
|
|
86140
86078
|
mkdirSync16(this.agentDir, { recursive: true });
|
|
86141
86079
|
}
|
|
86142
86080
|
this.dirCreated = true;
|
|
@@ -86146,14 +86084,14 @@ class DebugLogFile2 {
|
|
|
86146
86084
|
if (!this.agentDir)
|
|
86147
86085
|
return;
|
|
86148
86086
|
try {
|
|
86149
|
-
if (!
|
|
86087
|
+
if (!existsSync22(this.agentDir))
|
|
86150
86088
|
return;
|
|
86151
|
-
const files =
|
|
86089
|
+
const files = readdirSync10(this.agentDir).filter((f) => f.endsWith(".log")).sort();
|
|
86152
86090
|
if (files.length >= MAX_SESSION_FILES3) {
|
|
86153
86091
|
const toDelete = files.slice(0, files.length - MAX_SESSION_FILES3 + 1);
|
|
86154
86092
|
for (const file of toDelete) {
|
|
86155
86093
|
try {
|
|
86156
|
-
unlinkSync8(
|
|
86094
|
+
unlinkSync8(join30(this.agentDir, file));
|
|
86157
86095
|
} catch {}
|
|
86158
86096
|
}
|
|
86159
86097
|
}
|
|
@@ -86178,7 +86116,7 @@ function debugWarn2(prefix, message, ...args) {
|
|
|
86178
86116
|
}
|
|
86179
86117
|
var DEBUG_LOG_DIR2, MAX_SESSION_FILES3 = 5, DEFAULT_TAIL_LINES2 = 50, debugLogFile2;
|
|
86180
86118
|
var init_debug2 = __esm(() => {
|
|
86181
|
-
DEBUG_LOG_DIR2 =
|
|
86119
|
+
DEBUG_LOG_DIR2 = join30(homedir26(), ".letta", "logs", "debug");
|
|
86182
86120
|
debugLogFile2 = new DebugLogFile2;
|
|
86183
86121
|
});
|
|
86184
86122
|
|
|
@@ -86205,22 +86143,22 @@ __export(exports_skills2, {
|
|
|
86205
86143
|
SKILLS_DIR: () => SKILLS_DIR2,
|
|
86206
86144
|
GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR2
|
|
86207
86145
|
});
|
|
86208
|
-
import { existsSync as
|
|
86146
|
+
import { existsSync as existsSync23 } from "node:fs";
|
|
86209
86147
|
import { readdir as readdir7, readFile as readFile8, realpath as realpath4, stat as stat6 } from "node:fs/promises";
|
|
86210
|
-
import { dirname as dirname13, join as
|
|
86148
|
+
import { dirname as dirname13, join as join31 } from "node:path";
|
|
86211
86149
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
86212
86150
|
function getBundledSkillsPath2() {
|
|
86213
86151
|
const thisDir = dirname13(fileURLToPath8(import.meta.url));
|
|
86214
86152
|
if (thisDir.includes("src/agent") || thisDir.includes("src\\agent")) {
|
|
86215
|
-
return
|
|
86153
|
+
return join31(thisDir, "../skills/builtin");
|
|
86216
86154
|
}
|
|
86217
|
-
return
|
|
86155
|
+
return join31(thisDir, "skills");
|
|
86218
86156
|
}
|
|
86219
86157
|
function compareSkills2(a, b) {
|
|
86220
86158
|
return a.id.localeCompare(b.id) || a.source.localeCompare(b.source) || a.path.localeCompare(b.path);
|
|
86221
86159
|
}
|
|
86222
86160
|
function getAgentSkillsDir2(agentId) {
|
|
86223
|
-
return
|
|
86161
|
+
return join31(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "skills");
|
|
86224
86162
|
}
|
|
86225
86163
|
async function getBundledSkills2() {
|
|
86226
86164
|
const bundledPath = getBundledSkillsPath2();
|
|
@@ -86229,7 +86167,7 @@ async function getBundledSkills2() {
|
|
|
86229
86167
|
}
|
|
86230
86168
|
async function discoverSkillsFromDir2(skillsPath, source) {
|
|
86231
86169
|
const errors = [];
|
|
86232
|
-
if (!
|
|
86170
|
+
if (!existsSync23(skillsPath)) {
|
|
86233
86171
|
return { skills: [], errors: [] };
|
|
86234
86172
|
}
|
|
86235
86173
|
const skills = [];
|
|
@@ -86243,7 +86181,7 @@ async function discoverSkillsFromDir2(skillsPath, source) {
|
|
|
86243
86181
|
}
|
|
86244
86182
|
return { skills, errors };
|
|
86245
86183
|
}
|
|
86246
|
-
async function discoverSkills2(projectSkillsPath =
|
|
86184
|
+
async function discoverSkills2(projectSkillsPath = join31(process.cwd(), SKILLS_DIR2), agentId, options) {
|
|
86247
86185
|
const allErrors = [];
|
|
86248
86186
|
const skillsById = new Map;
|
|
86249
86187
|
const sourceSet = new Set(options?.sources ?? ALL_SKILL_SOURCES);
|
|
@@ -86298,7 +86236,7 @@ async function findSkillFiles2(currentPath, rootPath, skills, errors, source, vi
|
|
|
86298
86236
|
try {
|
|
86299
86237
|
const entries = await readdir7(currentPath, { withFileTypes: true });
|
|
86300
86238
|
for (const entry of entries) {
|
|
86301
|
-
const fullPath =
|
|
86239
|
+
const fullPath = join31(currentPath, entry.name);
|
|
86302
86240
|
try {
|
|
86303
86241
|
let isDirectory = entry.isDirectory();
|
|
86304
86242
|
let isFile = entry.isFile();
|
|
@@ -86387,7 +86325,7 @@ ${lines.join(`
|
|
|
86387
86325
|
var SKILLS_DIR2 = ".skills", GLOBAL_SKILLS_DIR2;
|
|
86388
86326
|
var init_skills2 = __esm(() => {
|
|
86389
86327
|
init_skillSources();
|
|
86390
|
-
GLOBAL_SKILLS_DIR2 =
|
|
86328
|
+
GLOBAL_SKILLS_DIR2 = join31(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
|
|
86391
86329
|
});
|
|
86392
86330
|
|
|
86393
86331
|
// src/utils/fs.ts
|
|
@@ -86401,7 +86339,7 @@ __export(exports_fs, {
|
|
|
86401
86339
|
exists: () => exists2
|
|
86402
86340
|
});
|
|
86403
86341
|
import {
|
|
86404
|
-
existsSync as
|
|
86342
|
+
existsSync as existsSync24,
|
|
86405
86343
|
readFileSync as fsReadFileSync2,
|
|
86406
86344
|
writeFileSync as fsWriteFileSync2,
|
|
86407
86345
|
mkdirSync as mkdirSync17
|
|
@@ -86412,13 +86350,13 @@ async function readFile9(path23) {
|
|
|
86412
86350
|
}
|
|
86413
86351
|
async function writeFile7(path23, content) {
|
|
86414
86352
|
const dir = dirname14(path23);
|
|
86415
|
-
if (!
|
|
86353
|
+
if (!existsSync24(dir)) {
|
|
86416
86354
|
mkdirSync17(dir, { recursive: true });
|
|
86417
86355
|
}
|
|
86418
86356
|
fsWriteFileSync2(path23, content, { encoding: "utf-8", flush: true });
|
|
86419
86357
|
}
|
|
86420
86358
|
function exists2(path23) {
|
|
86421
|
-
return
|
|
86359
|
+
return existsSync24(path23);
|
|
86422
86360
|
}
|
|
86423
86361
|
async function mkdir6(path23, options) {
|
|
86424
86362
|
mkdirSync17(path23, options);
|
|
@@ -86741,7 +86679,7 @@ __export(exports_auto_update, {
|
|
|
86741
86679
|
import { execFile as execFile13 } from "node:child_process";
|
|
86742
86680
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
86743
86681
|
import { readdir as readdir8, rm as rm3 } from "node:fs/promises";
|
|
86744
|
-
import { join as
|
|
86682
|
+
import { join as join32 } from "node:path";
|
|
86745
86683
|
import { promisify as promisify13 } from "node:util";
|
|
86746
86684
|
function debugLog3(...args) {
|
|
86747
86685
|
if (DEBUG) {
|
|
@@ -86906,12 +86844,12 @@ async function getNpmGlobalPath() {
|
|
|
86906
86844
|
}
|
|
86907
86845
|
}
|
|
86908
86846
|
async function cleanupOrphanedDirs(globalPath) {
|
|
86909
|
-
const lettaAiDir =
|
|
86847
|
+
const lettaAiDir = join32(globalPath, "lib/node_modules/@letta-ai");
|
|
86910
86848
|
try {
|
|
86911
86849
|
const entries = await readdir8(lettaAiDir);
|
|
86912
86850
|
for (const entry of entries) {
|
|
86913
86851
|
if (entry.startsWith(".letta-code-")) {
|
|
86914
|
-
const orphanPath =
|
|
86852
|
+
const orphanPath = join32(lettaAiDir, entry);
|
|
86915
86853
|
debugLog3("Cleaning orphaned temp directory:", orphanPath);
|
|
86916
86854
|
await rm3(orphanPath, { recursive: true, force: true });
|
|
86917
86855
|
}
|
|
@@ -87266,7 +87204,6 @@ __export(exports_promptAssets2, {
|
|
|
87266
87204
|
MEMORY_PROMPTS: () => MEMORY_PROMPTS2,
|
|
87267
87205
|
MEMORY_CHECK_REMINDER: () => MEMORY_CHECK_REMINDER2,
|
|
87268
87206
|
INTERRUPT_RECOVERY_ALERT: () => INTERRUPT_RECOVERY_ALERT2,
|
|
87269
|
-
AUTO_INIT_REMINDER: () => AUTO_INIT_REMINDER2,
|
|
87270
87207
|
APPROVAL_RECOVERY_PROMPT: () => APPROVAL_RECOVERY_PROMPT2
|
|
87271
87208
|
});
|
|
87272
87209
|
function scanHeadingsOutsideFences2(text) {
|
|
@@ -87397,10 +87334,9 @@ async function resolveSystemPrompt2(systemPromptPreset) {
|
|
|
87397
87334
|
}
|
|
87398
87335
|
throw new Error(`Unknown system prompt "${systemPromptPreset}" — does not match any preset or subagent`);
|
|
87399
87336
|
}
|
|
87400
|
-
var SYSTEM_PROMPT2, SYSTEM_PROMPT_BLOCKS_ADDON2, SYSTEM_PROMPT_MEMFS_ADDON2, PLAN_MODE_REMINDER2, SKILL_CREATOR_PROMPT2, REMEMBER_PROMPT2, MEMORY_CHECK_REMINDER2, APPROVAL_RECOVERY_PROMPT2,
|
|
87337
|
+
var SYSTEM_PROMPT2, SYSTEM_PROMPT_BLOCKS_ADDON2, SYSTEM_PROMPT_MEMFS_ADDON2, PLAN_MODE_REMINDER2, SKILL_CREATOR_PROMPT2, REMEMBER_PROMPT2, MEMORY_CHECK_REMINDER2, APPROVAL_RECOVERY_PROMPT2, INTERRUPT_RECOVERY_ALERT2, SLEEPTIME_MEMORY_PERSONA2, MEMORY_PROMPTS2, SYSTEM_PROMPTS2;
|
|
87401
87338
|
var init_promptAssets2 = __esm(() => {
|
|
87402
87339
|
init_approval_recovery_alert();
|
|
87403
|
-
init_auto_init_reminder();
|
|
87404
87340
|
init_human();
|
|
87405
87341
|
init_human_kawaii();
|
|
87406
87342
|
init_human_linus();
|
|
@@ -87432,7 +87368,6 @@ var init_promptAssets2 = __esm(() => {
|
|
|
87432
87368
|
REMEMBER_PROMPT2 = remember_default;
|
|
87433
87369
|
MEMORY_CHECK_REMINDER2 = memory_check_reminder_default;
|
|
87434
87370
|
APPROVAL_RECOVERY_PROMPT2 = approval_recovery_alert_default;
|
|
87435
|
-
AUTO_INIT_REMINDER2 = auto_init_reminder_default;
|
|
87436
87371
|
INTERRUPT_RECOVERY_ALERT2 = interrupt_recovery_alert_default;
|
|
87437
87372
|
SLEEPTIME_MEMORY_PERSONA2 = sleeptime_default;
|
|
87438
87373
|
MEMORY_PROMPTS2 = {
|
|
@@ -88208,8 +88143,8 @@ __export(exports_github_utils, {
|
|
|
88208
88143
|
async function fetchGitHubContents(owner, repo, branch, path25) {
|
|
88209
88144
|
const apiPath = path25 ? `repos/${owner}/${repo}/contents/${path25}?ref=${branch}` : `repos/${owner}/${repo}/contents?ref=${branch}`;
|
|
88210
88145
|
try {
|
|
88211
|
-
const { execSync:
|
|
88212
|
-
const result =
|
|
88146
|
+
const { execSync: execSync2 } = await import("node:child_process");
|
|
88147
|
+
const result = execSync2(`gh api ${apiPath}`, {
|
|
88213
88148
|
encoding: "utf-8",
|
|
88214
88149
|
stdio: ["pipe", "pipe", "ignore"]
|
|
88215
88150
|
});
|
|
@@ -88352,7 +88287,7 @@ function parseRegistryHandle(handle) {
|
|
|
88352
88287
|
}
|
|
88353
88288
|
async function importAgentFromRegistry(options) {
|
|
88354
88289
|
const { tmpdir: tmpdir4 } = await import("node:os");
|
|
88355
|
-
const { join:
|
|
88290
|
+
const { join: join34 } = await import("node:path");
|
|
88356
88291
|
const { writeFile: writeFile9, unlink: unlink3 } = await import("node:fs/promises");
|
|
88357
88292
|
const { author, name } = parseRegistryHandle(options.handle);
|
|
88358
88293
|
const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER}/${AGENT_REGISTRY_REPO}/refs/heads/${AGENT_REGISTRY_BRANCH}/agents/@${author}/${name}/${name}.af`;
|
|
@@ -88364,7 +88299,7 @@ async function importAgentFromRegistry(options) {
|
|
|
88364
88299
|
throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
|
|
88365
88300
|
}
|
|
88366
88301
|
const afContent = await response.text();
|
|
88367
|
-
const tempPath =
|
|
88302
|
+
const tempPath = join34(tmpdir4(), `letta-import-${author}-${name}-${Date.now()}.af`);
|
|
88368
88303
|
await writeFile9(tempPath, afContent, "utf-8");
|
|
88369
88304
|
try {
|
|
88370
88305
|
const result = await importAgentFromFile({
|
|
@@ -89896,12 +89831,16 @@ ${loadedContents.join(`
|
|
|
89896
89831
|
"tool_rule",
|
|
89897
89832
|
"no_tool_call"
|
|
89898
89833
|
];
|
|
89899
|
-
if (nonRetriableReasons.includes(stopReason)) {} else if (
|
|
89834
|
+
if (nonRetriableReasons.includes(stopReason)) {} else if (llmApiErrorRetries < LLM_API_ERROR_MAX_RETRIES2) {
|
|
89900
89835
|
try {
|
|
89901
|
-
|
|
89902
|
-
|
|
89903
|
-
|
|
89904
|
-
|
|
89836
|
+
let errorType;
|
|
89837
|
+
let detail = detailFromRun ?? latestErrorText ?? "";
|
|
89838
|
+
if (lastRunId) {
|
|
89839
|
+
const run = await client.runs.retrieve(lastRunId);
|
|
89840
|
+
const metaError = run.metadata?.error;
|
|
89841
|
+
errorType = metaError?.error_type ?? metaError?.error?.error_type;
|
|
89842
|
+
detail = metaError?.detail ?? metaError?.error?.detail ?? detail;
|
|
89843
|
+
}
|
|
89905
89844
|
if (isEmptyResponseRetryable(errorType, detail, emptyResponseRetries, EMPTY_RESPONSE_MAX_RETRIES2)) {
|
|
89906
89845
|
const attempt = emptyResponseRetries + 1;
|
|
89907
89846
|
const delayMs = getRetryDelayMs({
|
|
@@ -89964,7 +89903,37 @@ ${loadedContents.join(`
|
|
|
89964
89903
|
refreshCurrentInputOtids();
|
|
89965
89904
|
continue;
|
|
89966
89905
|
}
|
|
89967
|
-
} catch (_e) {
|
|
89906
|
+
} catch (_e) {
|
|
89907
|
+
if (shouldRetryRunMetadataError(undefined, detailFromRun ?? latestErrorText)) {
|
|
89908
|
+
const attempt = llmApiErrorRetries + 1;
|
|
89909
|
+
const detail = detailFromRun ?? latestErrorText;
|
|
89910
|
+
const delayMs = getRetryDelayMs({
|
|
89911
|
+
category: "transient_provider",
|
|
89912
|
+
attempt,
|
|
89913
|
+
detail
|
|
89914
|
+
});
|
|
89915
|
+
llmApiErrorRetries = attempt;
|
|
89916
|
+
if (outputFormat === "stream-json") {
|
|
89917
|
+
const retryMsg = {
|
|
89918
|
+
type: "retry",
|
|
89919
|
+
reason: "llm_api_error",
|
|
89920
|
+
attempt,
|
|
89921
|
+
max_attempts: LLM_API_ERROR_MAX_RETRIES2,
|
|
89922
|
+
delay_ms: delayMs,
|
|
89923
|
+
run_id: lastRunId ?? undefined,
|
|
89924
|
+
session_id: sessionId,
|
|
89925
|
+
uuid: `retry-${lastRunId || randomUUID8()}`
|
|
89926
|
+
};
|
|
89927
|
+
console.log(JSON.stringify(retryMsg));
|
|
89928
|
+
} else {
|
|
89929
|
+
const delaySeconds = Math.round(delayMs / 1000);
|
|
89930
|
+
console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
89931
|
+
}
|
|
89932
|
+
await new Promise((resolve27) => setTimeout(resolve27, delayMs));
|
|
89933
|
+
refreshCurrentInputOtids();
|
|
89934
|
+
continue;
|
|
89935
|
+
}
|
|
89936
|
+
}
|
|
89968
89937
|
}
|
|
89969
89938
|
markIncompleteToolsAsCancelled(buffers, true, "stream_error");
|
|
89970
89939
|
const errorLines = toLines(buffers).filter((line) => line.kind === "error");
|
|
@@ -91520,9 +91489,9 @@ __export(exports_settings, {
|
|
|
91520
91489
|
getSetting: () => getSetting
|
|
91521
91490
|
});
|
|
91522
91491
|
import { homedir as homedir29 } from "node:os";
|
|
91523
|
-
import { join as
|
|
91492
|
+
import { join as join35 } from "node:path";
|
|
91524
91493
|
function getSettingsPath() {
|
|
91525
|
-
return
|
|
91494
|
+
return join35(homedir29(), ".letta", "settings.json");
|
|
91526
91495
|
}
|
|
91527
91496
|
async function loadSettings() {
|
|
91528
91497
|
const settingsPath = getSettingsPath();
|
|
@@ -91559,7 +91528,7 @@ async function getSetting(key) {
|
|
|
91559
91528
|
return settings[key];
|
|
91560
91529
|
}
|
|
91561
91530
|
function getProjectSettingsPath() {
|
|
91562
|
-
return
|
|
91531
|
+
return join35(process.cwd(), ".letta", "settings.local.json");
|
|
91563
91532
|
}
|
|
91564
91533
|
async function loadProjectSettings() {
|
|
91565
91534
|
const settingsPath = getProjectSettingsPath();
|
|
@@ -91577,7 +91546,7 @@ async function loadProjectSettings() {
|
|
|
91577
91546
|
}
|
|
91578
91547
|
async function saveProjectSettings(settings) {
|
|
91579
91548
|
const settingsPath = getProjectSettingsPath();
|
|
91580
|
-
const dirPath =
|
|
91549
|
+
const dirPath = join35(process.cwd(), ".letta");
|
|
91581
91550
|
try {
|
|
91582
91551
|
if (!exists(dirPath)) {
|
|
91583
91552
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -108205,9 +108174,9 @@ function getFileEditHeader(toolName, toolArgs) {
|
|
|
108205
108174
|
const relPath = relative15(cwd2, filePath);
|
|
108206
108175
|
const displayPath = relPath.startsWith("..") ? filePath : relPath;
|
|
108207
108176
|
if (t === "write" || t === "write_file" || t === "writefile" || t === "write_file_gemini" || t === "writefilegemini") {
|
|
108208
|
-
const { existsSync:
|
|
108177
|
+
const { existsSync: existsSync27 } = __require("node:fs");
|
|
108209
108178
|
try {
|
|
108210
|
-
if (
|
|
108179
|
+
if (existsSync27(filePath)) {
|
|
108211
108180
|
return `Overwrite ${displayPath}?`;
|
|
108212
108181
|
}
|
|
108213
108182
|
} catch {}
|
|
@@ -108984,9 +108953,9 @@ function getHeaderText(fileEdit) {
|
|
|
108984
108953
|
const relPath = relative15(cwd2, fileEdit.filePath);
|
|
108985
108954
|
const displayPath = relPath.startsWith("..") ? fileEdit.filePath : relPath;
|
|
108986
108955
|
if (t === "write" || t === "write_file" || t === "writefile" || t === "write_file_gemini" || t === "writefilegemini") {
|
|
108987
|
-
const { existsSync:
|
|
108956
|
+
const { existsSync: existsSync27 } = __require("node:fs");
|
|
108988
108957
|
try {
|
|
108989
|
-
if (
|
|
108958
|
+
if (existsSync27(fileEdit.filePath)) {
|
|
108990
108959
|
return `Overwrite ${displayPath}?`;
|
|
108991
108960
|
}
|
|
108992
108961
|
} catch {}
|
|
@@ -111072,9 +111041,9 @@ html.dark .agent-name { color: var(--text-dim); }
|
|
|
111072
111041
|
var init_plan_viewer_template = () => {};
|
|
111073
111042
|
|
|
111074
111043
|
// src/web/generate-plan-viewer.ts
|
|
111075
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
111044
|
+
import { chmodSync as chmodSync2, existsSync as existsSync27, mkdirSync as mkdirSync20, writeFileSync as writeFileSync14 } from "node:fs";
|
|
111076
111045
|
import { homedir as homedir30 } from "node:os";
|
|
111077
|
-
import { join as
|
|
111046
|
+
import { join as join36 } from "node:path";
|
|
111078
111047
|
async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
|
|
111079
111048
|
const data = {
|
|
111080
111049
|
agent: { name: options?.agentName ?? "" },
|
|
@@ -111084,13 +111053,13 @@ async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
|
|
|
111084
111053
|
};
|
|
111085
111054
|
const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
|
|
111086
111055
|
const html = plan_viewer_template_default.replace("<!--LETTA_PLAN_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
111087
|
-
if (!
|
|
111056
|
+
if (!existsSync27(VIEWERS_DIR)) {
|
|
111088
111057
|
mkdirSync20(VIEWERS_DIR, { recursive: true, mode: 448 });
|
|
111089
111058
|
}
|
|
111090
111059
|
try {
|
|
111091
111060
|
chmodSync2(VIEWERS_DIR, 448);
|
|
111092
111061
|
} catch {}
|
|
111093
|
-
const filePath =
|
|
111062
|
+
const filePath = join36(VIEWERS_DIR, "plan.html");
|
|
111094
111063
|
writeFileSync14(filePath, html);
|
|
111095
111064
|
chmodSync2(filePath, 384);
|
|
111096
111065
|
const skipOpen = Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
|
|
@@ -111107,7 +111076,7 @@ async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
|
|
|
111107
111076
|
var VIEWERS_DIR;
|
|
111108
111077
|
var init_generate_plan_viewer = __esm(() => {
|
|
111109
111078
|
init_plan_viewer_template();
|
|
111110
|
-
VIEWERS_DIR =
|
|
111079
|
+
VIEWERS_DIR = join36(homedir30(), ".letta", "viewers");
|
|
111111
111080
|
});
|
|
111112
111081
|
|
|
111113
111082
|
// src/cli/components/StaticPlanApproval.tsx
|
|
@@ -113345,9 +113314,9 @@ var init_pasteRegistry = __esm(() => {
|
|
|
113345
113314
|
|
|
113346
113315
|
// src/cli/helpers/clipboard.ts
|
|
113347
113316
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
113348
|
-
import { existsSync as
|
|
113317
|
+
import { existsSync as existsSync28, readFileSync as readFileSync15, statSync as statSync10, unlinkSync as unlinkSync10 } from "node:fs";
|
|
113349
113318
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
113350
|
-
import { basename as basename5, extname as extname5, isAbsolute as isAbsolute19, join as
|
|
113319
|
+
import { basename as basename5, extname as extname5, isAbsolute as isAbsolute19, join as join37, resolve as resolve27 } from "node:path";
|
|
113351
113320
|
function countLines2(text) {
|
|
113352
113321
|
return (text.match(/\r\n|\r|\n/g) || []).length + 1;
|
|
113353
113322
|
}
|
|
@@ -113397,8 +113366,8 @@ function translatePasteForImages(paste) {
|
|
|
113397
113366
|
if (!isAbsolute19(filePath))
|
|
113398
113367
|
filePath = resolve27(process.cwd(), filePath);
|
|
113399
113368
|
const ext3 = extname5(filePath || "").toLowerCase();
|
|
113400
|
-
if (IMAGE_EXTS.has(ext3) &&
|
|
113401
|
-
const buf =
|
|
113369
|
+
if (IMAGE_EXTS.has(ext3) && existsSync28(filePath) && statSync10(filePath).isFile()) {
|
|
113370
|
+
const buf = readFileSync15(filePath);
|
|
113402
113371
|
const b64 = buf.toString("base64");
|
|
113403
113372
|
const mt = ext3 === ".png" ? "image/png" : ext3 === ".jpg" || ext3 === ".jpeg" ? "image/jpeg" : ext3 === ".gif" ? "image/gif" : ext3 === ".webp" ? "image/webp" : ext3 === ".bmp" ? "image/bmp" : ext3 === ".svg" ? "image/svg+xml" : ext3 === ".tif" || ext3 === ".tiff" ? "image/tiff" : ext3 === ".heic" ? "image/heic" : ext3 === ".heif" ? "image/heif" : ext3 === ".avif" ? "image/avif" : "application/octet-stream";
|
|
113404
113373
|
const id = allocateImage({
|
|
@@ -113415,7 +113384,7 @@ function translatePasteForImages(paste) {
|
|
|
113415
113384
|
function getClipboardImageToTempFile() {
|
|
113416
113385
|
if (process.platform !== "darwin")
|
|
113417
113386
|
return null;
|
|
113418
|
-
const tempPath =
|
|
113387
|
+
const tempPath = join37(tmpdir4(), `letta-clipboard-${Date.now()}.bin`);
|
|
113419
113388
|
try {
|
|
113420
113389
|
const jxa = `
|
|
113421
113390
|
ObjC.import('AppKit');
|
|
@@ -113438,11 +113407,11 @@ function getClipboardImageToTempFile() {
|
|
|
113438
113407
|
encoding: "utf8",
|
|
113439
113408
|
stdio: ["ignore", "pipe", "ignore"]
|
|
113440
113409
|
}).trim();
|
|
113441
|
-
if (!uti || !
|
|
113410
|
+
if (!uti || !existsSync28(tempPath))
|
|
113442
113411
|
return null;
|
|
113443
113412
|
return { tempPath, uti };
|
|
113444
113413
|
} catch {
|
|
113445
|
-
if (
|
|
113414
|
+
if (existsSync28(tempPath)) {
|
|
113446
113415
|
try {
|
|
113447
113416
|
unlinkSync10(tempPath);
|
|
113448
113417
|
} catch {}
|
|
@@ -113458,7 +113427,7 @@ async function tryImportClipboardImageMac() {
|
|
|
113458
113427
|
return null;
|
|
113459
113428
|
const { tempPath, uti } = clipboardResult;
|
|
113460
113429
|
try {
|
|
113461
|
-
const buffer =
|
|
113430
|
+
const buffer = readFileSync15(tempPath);
|
|
113462
113431
|
try {
|
|
113463
113432
|
unlinkSync10(tempPath);
|
|
113464
113433
|
} catch {}
|
|
@@ -113475,7 +113444,7 @@ async function tryImportClipboardImageMac() {
|
|
|
113475
113444
|
height: resized.height
|
|
113476
113445
|
};
|
|
113477
113446
|
} catch (err) {
|
|
113478
|
-
if (
|
|
113447
|
+
if (existsSync28(tempPath)) {
|
|
113479
113448
|
try {
|
|
113480
113449
|
unlinkSync10(tempPath);
|
|
113481
113450
|
} catch {}
|
|
@@ -114165,13 +114134,13 @@ __export(exports_terminalKeybindingInstaller, {
|
|
|
114165
114134
|
});
|
|
114166
114135
|
import {
|
|
114167
114136
|
copyFileSync,
|
|
114168
|
-
existsSync as
|
|
114137
|
+
existsSync as existsSync29,
|
|
114169
114138
|
mkdirSync as mkdirSync21,
|
|
114170
|
-
readFileSync as
|
|
114139
|
+
readFileSync as readFileSync16,
|
|
114171
114140
|
writeFileSync as writeFileSync15
|
|
114172
114141
|
} from "node:fs";
|
|
114173
114142
|
import { homedir as homedir31, platform as platform5 } from "node:os";
|
|
114174
|
-
import { dirname as dirname16, join as
|
|
114143
|
+
import { dirname as dirname16, join as join38 } from "node:path";
|
|
114175
114144
|
function detectTerminalType() {
|
|
114176
114145
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
114177
114146
|
return "cursor";
|
|
@@ -114203,16 +114172,16 @@ function getKeybindingsPath(terminal) {
|
|
|
114203
114172
|
}[terminal];
|
|
114204
114173
|
const os7 = platform5();
|
|
114205
114174
|
if (os7 === "darwin") {
|
|
114206
|
-
return
|
|
114175
|
+
return join38(homedir31(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
114207
114176
|
}
|
|
114208
114177
|
if (os7 === "win32") {
|
|
114209
114178
|
const appData = process.env.APPDATA;
|
|
114210
114179
|
if (!appData)
|
|
114211
114180
|
return null;
|
|
114212
|
-
return
|
|
114181
|
+
return join38(appData, appName, "User", "keybindings.json");
|
|
114213
114182
|
}
|
|
114214
114183
|
if (os7 === "linux") {
|
|
114215
|
-
return
|
|
114184
|
+
return join38(homedir31(), ".config", appName, "User", "keybindings.json");
|
|
114216
114185
|
}
|
|
114217
114186
|
return null;
|
|
114218
114187
|
}
|
|
@@ -114234,10 +114203,10 @@ function parseKeybindings(content) {
|
|
|
114234
114203
|
}
|
|
114235
114204
|
}
|
|
114236
114205
|
function keybindingExists(keybindingsPath) {
|
|
114237
|
-
if (!
|
|
114206
|
+
if (!existsSync29(keybindingsPath))
|
|
114238
114207
|
return false;
|
|
114239
114208
|
try {
|
|
114240
|
-
const content =
|
|
114209
|
+
const content = readFileSync16(keybindingsPath, { encoding: "utf-8" });
|
|
114241
114210
|
const keybindings = parseKeybindings(content);
|
|
114242
114211
|
if (!keybindings)
|
|
114243
114212
|
return false;
|
|
@@ -114247,7 +114216,7 @@ function keybindingExists(keybindingsPath) {
|
|
|
114247
114216
|
}
|
|
114248
114217
|
}
|
|
114249
114218
|
function createBackup(keybindingsPath) {
|
|
114250
|
-
if (!
|
|
114219
|
+
if (!existsSync29(keybindingsPath))
|
|
114251
114220
|
return null;
|
|
114252
114221
|
const backupPath = `${keybindingsPath}.letta-backup`;
|
|
114253
114222
|
try {
|
|
@@ -114263,14 +114232,14 @@ function installKeybinding(keybindingsPath) {
|
|
|
114263
114232
|
return { success: true, alreadyExists: true };
|
|
114264
114233
|
}
|
|
114265
114234
|
const parentDir = dirname16(keybindingsPath);
|
|
114266
|
-
if (!
|
|
114235
|
+
if (!existsSync29(parentDir)) {
|
|
114267
114236
|
mkdirSync21(parentDir, { recursive: true });
|
|
114268
114237
|
}
|
|
114269
114238
|
let keybindings = [];
|
|
114270
114239
|
let backupPath = null;
|
|
114271
|
-
if (
|
|
114240
|
+
if (existsSync29(keybindingsPath)) {
|
|
114272
114241
|
backupPath = createBackup(keybindingsPath);
|
|
114273
|
-
const content =
|
|
114242
|
+
const content = readFileSync16(keybindingsPath, { encoding: "utf-8" });
|
|
114274
114243
|
const parsed = parseKeybindings(content);
|
|
114275
114244
|
if (parsed === null) {
|
|
114276
114245
|
return {
|
|
@@ -114298,10 +114267,10 @@ function installKeybinding(keybindingsPath) {
|
|
|
114298
114267
|
}
|
|
114299
114268
|
function removeKeybinding(keybindingsPath) {
|
|
114300
114269
|
try {
|
|
114301
|
-
if (!
|
|
114270
|
+
if (!existsSync29(keybindingsPath)) {
|
|
114302
114271
|
return { success: true };
|
|
114303
114272
|
}
|
|
114304
|
-
const content =
|
|
114273
|
+
const content = readFileSync16(keybindingsPath, { encoding: "utf-8" });
|
|
114305
114274
|
const keybindings = parseKeybindings(content);
|
|
114306
114275
|
if (!keybindings) {
|
|
114307
114276
|
return {
|
|
@@ -114365,20 +114334,20 @@ function getWezTermConfigPath() {
|
|
|
114365
114334
|
}
|
|
114366
114335
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
114367
114336
|
if (xdgConfig) {
|
|
114368
|
-
const xdgPath =
|
|
114369
|
-
if (
|
|
114337
|
+
const xdgPath = join38(xdgConfig, "wezterm", "wezterm.lua");
|
|
114338
|
+
if (existsSync29(xdgPath))
|
|
114370
114339
|
return xdgPath;
|
|
114371
114340
|
}
|
|
114372
|
-
const configPath =
|
|
114373
|
-
if (
|
|
114341
|
+
const configPath = join38(homedir31(), ".config", "wezterm", "wezterm.lua");
|
|
114342
|
+
if (existsSync29(configPath))
|
|
114374
114343
|
return configPath;
|
|
114375
|
-
return
|
|
114344
|
+
return join38(homedir31(), ".wezterm.lua");
|
|
114376
114345
|
}
|
|
114377
114346
|
function wezTermDeleteFixExists(configPath) {
|
|
114378
|
-
if (!
|
|
114347
|
+
if (!existsSync29(configPath))
|
|
114379
114348
|
return false;
|
|
114380
114349
|
try {
|
|
114381
|
-
const content =
|
|
114350
|
+
const content = readFileSync16(configPath, { encoding: "utf-8" });
|
|
114382
114351
|
return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
|
|
114383
114352
|
} catch {
|
|
114384
114353
|
return false;
|
|
@@ -114392,10 +114361,10 @@ function installWezTermDeleteFix() {
|
|
|
114392
114361
|
}
|
|
114393
114362
|
let content = "";
|
|
114394
114363
|
let backupPath = null;
|
|
114395
|
-
if (
|
|
114364
|
+
if (existsSync29(configPath)) {
|
|
114396
114365
|
backupPath = `${configPath}.letta-backup`;
|
|
114397
114366
|
copyFileSync(configPath, backupPath);
|
|
114398
|
-
content =
|
|
114367
|
+
content = readFileSync16(configPath, { encoding: "utf-8" });
|
|
114399
114368
|
}
|
|
114400
114369
|
if (content.includes("return {") && !content.includes("local config")) {
|
|
114401
114370
|
content = content.replace(/return\s*\{/, "local config = {");
|
|
@@ -114422,7 +114391,7 @@ ${WEZTERM_DELETE_FIX}
|
|
|
114422
114391
|
`;
|
|
114423
114392
|
}
|
|
114424
114393
|
const parentDir = dirname16(configPath);
|
|
114425
|
-
if (!
|
|
114394
|
+
if (!existsSync29(parentDir)) {
|
|
114426
114395
|
mkdirSync21(parentDir, { recursive: true });
|
|
114427
114396
|
}
|
|
114428
114397
|
writeFileSync15(configPath, content, { encoding: "utf-8" });
|
|
@@ -115002,9 +114971,9 @@ __export(exports_custom, {
|
|
|
115002
114971
|
GLOBAL_COMMANDS_DIR: () => GLOBAL_COMMANDS_DIR,
|
|
115003
114972
|
COMMANDS_DIR: () => COMMANDS_DIR
|
|
115004
114973
|
});
|
|
115005
|
-
import { existsSync as
|
|
114974
|
+
import { existsSync as existsSync30 } from "node:fs";
|
|
115006
114975
|
import { readdir as readdir9, readFile as readFile11 } from "node:fs/promises";
|
|
115007
|
-
import { basename as basename6, dirname as dirname17, join as
|
|
114976
|
+
import { basename as basename6, dirname as dirname17, join as join39 } from "node:path";
|
|
115008
114977
|
async function getCustomCommands() {
|
|
115009
114978
|
if (cachedCommands !== null) {
|
|
115010
114979
|
return cachedCommands;
|
|
@@ -115015,7 +114984,7 @@ async function getCustomCommands() {
|
|
|
115015
114984
|
function refreshCustomCommands() {
|
|
115016
114985
|
cachedCommands = null;
|
|
115017
114986
|
}
|
|
115018
|
-
async function discoverCustomCommands(projectPath =
|
|
114987
|
+
async function discoverCustomCommands(projectPath = join39(process.cwd(), COMMANDS_DIR)) {
|
|
115019
114988
|
const commandsById = new Map;
|
|
115020
114989
|
const userCommands = await discoverFromDirectory(GLOBAL_COMMANDS_DIR, "user");
|
|
115021
114990
|
for (const cmd of userCommands) {
|
|
@@ -115036,7 +115005,7 @@ async function discoverCustomCommands(projectPath = join40(process.cwd(), COMMAN
|
|
|
115036
115005
|
return result;
|
|
115037
115006
|
}
|
|
115038
115007
|
async function discoverFromDirectory(dirPath, source2) {
|
|
115039
|
-
if (!
|
|
115008
|
+
if (!existsSync30(dirPath)) {
|
|
115040
115009
|
return [];
|
|
115041
115010
|
}
|
|
115042
115011
|
const commands2 = [];
|
|
@@ -115047,7 +115016,7 @@ async function findCommandFiles(currentPath, rootPath, commands2, source2) {
|
|
|
115047
115016
|
try {
|
|
115048
115017
|
const entries = await readdir9(currentPath, { withFileTypes: true });
|
|
115049
115018
|
for (const entry of entries) {
|
|
115050
|
-
const fullPath =
|
|
115019
|
+
const fullPath = join39(currentPath, entry.name);
|
|
115051
115020
|
if (entry.isDirectory()) {
|
|
115052
115021
|
await findCommandFiles(fullPath, rootPath, commands2, source2);
|
|
115053
115022
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
@@ -115132,7 +115101,7 @@ async function findCustomCommand(commandName) {
|
|
|
115132
115101
|
}
|
|
115133
115102
|
var COMMANDS_DIR = ".commands", GLOBAL_COMMANDS_DIR, cachedCommands = null;
|
|
115134
115103
|
var init_custom = __esm(() => {
|
|
115135
|
-
GLOBAL_COMMANDS_DIR =
|
|
115104
|
+
GLOBAL_COMMANDS_DIR = join39(process.env.HOME || process.env.USERPROFILE || "~", ".letta/commands");
|
|
115136
115105
|
});
|
|
115137
115106
|
|
|
115138
115107
|
// src/cli/components/HelpDialog.tsx
|
|
@@ -118055,17 +118024,17 @@ var init_AgentInfoBar = __esm(async () => {
|
|
|
118055
118024
|
});
|
|
118056
118025
|
|
|
118057
118026
|
// src/cli/helpers/fileSearch.ts
|
|
118058
|
-
import { readdirSync as
|
|
118059
|
-
import { join as
|
|
118027
|
+
import { readdirSync as readdirSync12, statSync as statSync11 } from "node:fs";
|
|
118028
|
+
import { join as join40, relative as relative15, resolve as resolve29 } from "node:path";
|
|
118060
118029
|
function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = [], depth = 0, maxDepth = 10, lowerPattern = pattern.toLowerCase()) {
|
|
118061
118030
|
if (results.length >= maxResults || depth >= maxDepth) {
|
|
118062
118031
|
return results;
|
|
118063
118032
|
}
|
|
118064
118033
|
try {
|
|
118065
|
-
const entries =
|
|
118034
|
+
const entries = readdirSync12(dir);
|
|
118066
118035
|
for (const entry of entries) {
|
|
118067
118036
|
try {
|
|
118068
|
-
const fullPath =
|
|
118037
|
+
const fullPath = join40(dir, entry);
|
|
118069
118038
|
const relativePath = relative15(getIndexRoot(), fullPath);
|
|
118070
118039
|
if (shouldHardExcludeEntry(entry, getIndexRoot())) {
|
|
118071
118040
|
continue;
|
|
@@ -118135,7 +118104,7 @@ async function searchFiles(query, deep = false) {
|
|
|
118135
118104
|
} else {
|
|
118136
118105
|
let entries = [];
|
|
118137
118106
|
try {
|
|
118138
|
-
entries =
|
|
118107
|
+
entries = readdirSync12(searchDir);
|
|
118139
118108
|
} catch {
|
|
118140
118109
|
return [];
|
|
118141
118110
|
}
|
|
@@ -118143,7 +118112,7 @@ async function searchFiles(query, deep = false) {
|
|
|
118143
118112
|
const matchingEntries = entries.filter((entry) => !shouldHardExcludeEntry(entry, getIndexRoot()) && (searchPattern.length === 0 || entry.toLowerCase().includes(lowerPattern)));
|
|
118144
118113
|
for (const entry of matchingEntries.slice(0, 50)) {
|
|
118145
118114
|
try {
|
|
118146
|
-
const fullPath =
|
|
118115
|
+
const fullPath = join40(searchDir, entry);
|
|
118147
118116
|
const stats = statSync11(fullPath);
|
|
118148
118117
|
const relativePath = relative15(getIndexRoot(), fullPath);
|
|
118149
118118
|
results.push({
|
|
@@ -120219,15 +120188,15 @@ var init_InputRich = __esm(async () => {
|
|
|
120219
120188
|
// src/cli/commands/install-github-app.ts
|
|
120220
120189
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
120221
120190
|
import {
|
|
120222
|
-
existsSync as
|
|
120191
|
+
existsSync as existsSync31,
|
|
120223
120192
|
mkdirSync as mkdirSync22,
|
|
120224
120193
|
mkdtempSync,
|
|
120225
|
-
readFileSync as
|
|
120194
|
+
readFileSync as readFileSync17,
|
|
120226
120195
|
rmSync as rmSync4,
|
|
120227
120196
|
writeFileSync as writeFileSync16
|
|
120228
120197
|
} from "node:fs";
|
|
120229
120198
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
120230
|
-
import { dirname as dirname18, join as
|
|
120199
|
+
import { dirname as dirname18, join as join41 } from "node:path";
|
|
120231
120200
|
function runCommand(command, args, cwd2, input) {
|
|
120232
120201
|
try {
|
|
120233
120202
|
return execFileSync4(command, args, {
|
|
@@ -120461,8 +120430,8 @@ async function createLettaAgent(apiKey, name) {
|
|
|
120461
120430
|
return { id: data.id, name: data.name };
|
|
120462
120431
|
}
|
|
120463
120432
|
function cloneRepoToTemp(repo) {
|
|
120464
|
-
const tempDir = mkdtempSync(
|
|
120465
|
-
const repoDir =
|
|
120433
|
+
const tempDir = mkdtempSync(join41(tmpdir5(), "letta-install-github-app-"));
|
|
120434
|
+
const repoDir = join41(tempDir, "repo");
|
|
120466
120435
|
runCommand("gh", ["repo", "clone", repo, repoDir, "--", "--depth=1"]);
|
|
120467
120436
|
return { tempDir, repoDir };
|
|
120468
120437
|
}
|
|
@@ -120473,14 +120442,14 @@ function runGit6(args, cwd2) {
|
|
|
120473
120442
|
return runCommand("git", args, cwd2);
|
|
120474
120443
|
}
|
|
120475
120444
|
function writeWorkflow(repoDir, workflowPath, content) {
|
|
120476
|
-
const absolutePath =
|
|
120477
|
-
if (!
|
|
120445
|
+
const absolutePath = join41(repoDir, workflowPath);
|
|
120446
|
+
if (!existsSync31(dirname18(absolutePath))) {
|
|
120478
120447
|
mkdirSync22(dirname18(absolutePath), { recursive: true });
|
|
120479
120448
|
}
|
|
120480
120449
|
const next = `${content.trimEnd()}
|
|
120481
120450
|
`;
|
|
120482
|
-
if (
|
|
120483
|
-
const previous =
|
|
120451
|
+
if (existsSync31(absolutePath)) {
|
|
120452
|
+
const previous = readFileSync17(absolutePath, "utf8");
|
|
120484
120453
|
if (previous === next) {
|
|
120485
120454
|
return false;
|
|
120486
120455
|
}
|
|
@@ -124380,9 +124349,9 @@ __export(exports_generate_memory_viewer, {
|
|
|
124380
124349
|
generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
|
|
124381
124350
|
});
|
|
124382
124351
|
import { execFile as execFileCb5 } from "node:child_process";
|
|
124383
|
-
import { chmodSync as chmodSync3, existsSync as
|
|
124352
|
+
import { chmodSync as chmodSync3, existsSync as existsSync32, mkdirSync as mkdirSync23, writeFileSync as writeFileSync17 } from "node:fs";
|
|
124384
124353
|
import { homedir as homedir33 } from "node:os";
|
|
124385
|
-
import { join as
|
|
124354
|
+
import { join as join42 } from "node:path";
|
|
124386
124355
|
import { promisify as promisify14 } from "node:util";
|
|
124387
124356
|
async function runGitSafe(cwd2, args) {
|
|
124388
124357
|
try {
|
|
@@ -124665,13 +124634,13 @@ async function generateAndOpenMemoryViewer(agentId, options) {
|
|
|
124665
124634
|
}
|
|
124666
124635
|
const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
|
|
124667
124636
|
const html = memory_viewer_template_default.replace("<!--LETTA_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
124668
|
-
if (!
|
|
124637
|
+
if (!existsSync32(VIEWERS_DIR2)) {
|
|
124669
124638
|
mkdirSync23(VIEWERS_DIR2, { recursive: true, mode: 448 });
|
|
124670
124639
|
}
|
|
124671
124640
|
try {
|
|
124672
124641
|
chmodSync3(VIEWERS_DIR2, 448);
|
|
124673
124642
|
} catch {}
|
|
124674
|
-
const filePath =
|
|
124643
|
+
const filePath = join42(VIEWERS_DIR2, `memory-${encodeURIComponent(agentId)}.html`);
|
|
124675
124644
|
writeFileSync17(filePath, html);
|
|
124676
124645
|
chmodSync3(filePath, 384);
|
|
124677
124646
|
const skipOpen = Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
|
|
@@ -124695,12 +124664,12 @@ var init_generate_memory_viewer = __esm(async () => {
|
|
|
124695
124664
|
init_memoryGit()
|
|
124696
124665
|
]);
|
|
124697
124666
|
execFile14 = promisify14(execFileCb5);
|
|
124698
|
-
VIEWERS_DIR2 =
|
|
124667
|
+
VIEWERS_DIR2 = join42(homedir33(), ".letta", "viewers");
|
|
124699
124668
|
REFLECTION_PATTERN = /\(reflection\)|🔮|reflection:/i;
|
|
124700
124669
|
});
|
|
124701
124670
|
|
|
124702
124671
|
// src/cli/components/MemfsTreeViewer.tsx
|
|
124703
|
-
import { existsSync as
|
|
124672
|
+
import { existsSync as existsSync33 } from "node:fs";
|
|
124704
124673
|
function renderTreePrefix(node) {
|
|
124705
124674
|
let prefix = "";
|
|
124706
124675
|
for (let i = 0;i < node.depth; i++) {
|
|
@@ -124726,7 +124695,7 @@ function MemfsTreeViewer({
|
|
|
124726
124695
|
const [status, setStatus] = import_react78.useState(null);
|
|
124727
124696
|
const statusTimerRef = import_react78.useRef(null);
|
|
124728
124697
|
const memoryRoot = getMemoryFilesystemRoot(agentId);
|
|
124729
|
-
const memoryExists =
|
|
124698
|
+
const memoryExists = existsSync33(memoryRoot);
|
|
124730
124699
|
const hasGitRepo = import_react78.useMemo(() => isGitRepo(agentId), [agentId]);
|
|
124731
124700
|
function showStatus(msg, durationMs) {
|
|
124732
124701
|
if (statusTimerRef.current)
|
|
@@ -127414,10 +127383,10 @@ var init_PersonalitySelector = __esm(async () => {
|
|
|
127414
127383
|
// src/utils/aws-credentials.ts
|
|
127415
127384
|
import { readFile as readFile12 } from "node:fs/promises";
|
|
127416
127385
|
import { homedir as homedir34 } from "node:os";
|
|
127417
|
-
import { join as
|
|
127386
|
+
import { join as join43 } from "node:path";
|
|
127418
127387
|
async function parseAwsCredentials() {
|
|
127419
|
-
const credentialsPath =
|
|
127420
|
-
const configPath =
|
|
127388
|
+
const credentialsPath = join43(homedir34(), ".aws", "credentials");
|
|
127389
|
+
const configPath = join43(homedir34(), ".aws", "config");
|
|
127421
127390
|
const profiles = new Map;
|
|
127422
127391
|
try {
|
|
127423
127392
|
const content = await readFile12(credentialsPath, "utf-8");
|
|
@@ -128525,8 +128494,8 @@ function SkillsDialog({ onClose, agentId }) {
|
|
|
128525
128494
|
try {
|
|
128526
128495
|
const { discoverSkills: discoverSkills3, SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills(), exports_skills));
|
|
128527
128496
|
const { getSkillsDirectory: getSkillsDirectory2, getSkillSources: getSkillSources2 } = await Promise.resolve().then(() => (init_context(), exports_context));
|
|
128528
|
-
const { join:
|
|
128529
|
-
const skillsDir = getSkillsDirectory2() ||
|
|
128497
|
+
const { join: join44 } = await import("node:path");
|
|
128498
|
+
const skillsDir = getSkillsDirectory2() || join44(process.cwd(), SKILLS_DIR3);
|
|
128530
128499
|
const result = await discoverSkills3(skillsDir, agentId, {
|
|
128531
128500
|
sources: getSkillSources2()
|
|
128532
128501
|
});
|
|
@@ -132517,27 +132486,27 @@ var init_reasoningTabToggle = __esm(() => {
|
|
|
132517
132486
|
});
|
|
132518
132487
|
|
|
132519
132488
|
// src/cli/helpers/startupSystemPromptWarning.ts
|
|
132520
|
-
import { existsSync as
|
|
132521
|
-
import { join as
|
|
132489
|
+
import { existsSync as existsSync34, readdirSync as readdirSync13, readFileSync as readFileSync18 } from "node:fs";
|
|
132490
|
+
import { join as join44 } from "node:path";
|
|
132522
132491
|
function estimateSystemTokens(text) {
|
|
132523
132492
|
return Math.ceil(Buffer.byteLength(text, "utf8") / STARTUP_SYSTEM_PROMPT_ESTIMATED_BYTES_PER_TOKEN);
|
|
132524
132493
|
}
|
|
132525
132494
|
function estimateSystemPromptTokensFromMemoryDir(memoryDir) {
|
|
132526
|
-
const systemDir =
|
|
132527
|
-
if (!
|
|
132495
|
+
const systemDir = join44(memoryDir, "system");
|
|
132496
|
+
if (!existsSync34(systemDir)) {
|
|
132528
132497
|
return 0;
|
|
132529
132498
|
}
|
|
132530
132499
|
const walkMarkdownFiles = (dir) => {
|
|
132531
|
-
if (!
|
|
132500
|
+
if (!existsSync34(dir)) {
|
|
132532
132501
|
return [];
|
|
132533
132502
|
}
|
|
132534
132503
|
const out = [];
|
|
132535
|
-
const entries =
|
|
132504
|
+
const entries = readdirSync13(dir, { withFileTypes: true });
|
|
132536
132505
|
for (const entry of entries) {
|
|
132537
132506
|
if (entry.name.startsWith(".")) {
|
|
132538
132507
|
continue;
|
|
132539
132508
|
}
|
|
132540
|
-
const full =
|
|
132509
|
+
const full = join44(dir, entry.name);
|
|
132541
132510
|
if (entry.isDirectory()) {
|
|
132542
132511
|
if (entry.name === ".git") {
|
|
132543
132512
|
continue;
|
|
@@ -132552,7 +132521,7 @@ function estimateSystemPromptTokensFromMemoryDir(memoryDir) {
|
|
|
132552
132521
|
return out;
|
|
132553
132522
|
};
|
|
132554
132523
|
return walkMarkdownFiles(systemDir).sort().reduce((sum, filePath) => {
|
|
132555
|
-
const text =
|
|
132524
|
+
const text = readFileSync18(filePath, "utf8");
|
|
132556
132525
|
return sum + estimateSystemTokens(text);
|
|
132557
132526
|
}, 0);
|
|
132558
132527
|
}
|
|
@@ -133356,16 +133325,16 @@ __export(exports_shellAliases, {
|
|
|
133356
133325
|
expandAliases: () => expandAliases,
|
|
133357
133326
|
clearAliasCache: () => clearAliasCache
|
|
133358
133327
|
});
|
|
133359
|
-
import { existsSync as
|
|
133328
|
+
import { existsSync as existsSync35, readFileSync as readFileSync19 } from "node:fs";
|
|
133360
133329
|
import { homedir as homedir35 } from "node:os";
|
|
133361
|
-
import { join as
|
|
133330
|
+
import { join as join45 } from "node:path";
|
|
133362
133331
|
function parseAliasesFromFile(filePath) {
|
|
133363
133332
|
const aliases = new Map;
|
|
133364
|
-
if (!
|
|
133333
|
+
if (!existsSync35(filePath)) {
|
|
133365
133334
|
return aliases;
|
|
133366
133335
|
}
|
|
133367
133336
|
try {
|
|
133368
|
-
const content =
|
|
133337
|
+
const content = readFileSync19(filePath, "utf-8");
|
|
133369
133338
|
const lines = content.split(`
|
|
133370
133339
|
`);
|
|
133371
133340
|
let inFunction = false;
|
|
@@ -133430,7 +133399,7 @@ function loadAliases(forceReload = false) {
|
|
|
133430
133399
|
const home = homedir35();
|
|
133431
133400
|
const allAliases = new Map;
|
|
133432
133401
|
for (const file of ALIAS_FILES) {
|
|
133433
|
-
const filePath =
|
|
133402
|
+
const filePath = join45(home, file);
|
|
133434
133403
|
const fileAliases = parseAliasesFromFile(filePath);
|
|
133435
133404
|
for (const [name, value] of fileAliases) {
|
|
133436
133405
|
allAliases.set(name, value);
|
|
@@ -134280,9 +134249,9 @@ __export(exports_App, {
|
|
|
134280
134249
|
default: () => App2
|
|
134281
134250
|
});
|
|
134282
134251
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
134283
|
-
import { existsSync as
|
|
134252
|
+
import { existsSync as existsSync36, readFileSync as readFileSync20, renameSync as renameSync3, writeFileSync as writeFileSync18 } from "node:fs";
|
|
134284
134253
|
import { homedir as homedir36, tmpdir as tmpdir6 } from "node:os";
|
|
134285
|
-
import { join as
|
|
134254
|
+
import { join as join46, relative as relative17 } from "node:path";
|
|
134286
134255
|
function deriveReasoningEffort(modelSettings, llmConfig) {
|
|
134287
134256
|
if (modelSettings && "provider_type" in modelSettings) {
|
|
134288
134257
|
if (modelSettings.provider_type === "openai" && "reasoning" in modelSettings && modelSettings.reasoning) {
|
|
@@ -134489,7 +134458,7 @@ function sendDesktopNotification(message = "Awaiting your input", level = "info"
|
|
|
134489
134458
|
debugLog("hooks", "Notification hook error", error);
|
|
134490
134459
|
});
|
|
134491
134460
|
}
|
|
134492
|
-
async function isRetriableError(stopReason, lastRunId) {
|
|
134461
|
+
async function isRetriableError(stopReason, lastRunId, fallbackDetail) {
|
|
134493
134462
|
if (stopReason === "llm_api_error")
|
|
134494
134463
|
return true;
|
|
134495
134464
|
const nonRetriableReasons = [
|
|
@@ -134516,10 +134485,10 @@ async function isRetriableError(stopReason, lastRunId) {
|
|
|
134516
134485
|
}
|
|
134517
134486
|
return false;
|
|
134518
134487
|
} catch {
|
|
134519
|
-
return
|
|
134488
|
+
return shouldRetryRunMetadataError(undefined, fallbackDetail);
|
|
134520
134489
|
}
|
|
134521
134490
|
}
|
|
134522
|
-
return
|
|
134491
|
+
return shouldRetryRunMetadataError(undefined, fallbackDetail);
|
|
134523
134492
|
}
|
|
134524
134493
|
function saveLastSessionBeforeExit(conversationId) {
|
|
134525
134494
|
try {
|
|
@@ -134534,18 +134503,18 @@ function saveLastSessionBeforeExit(conversationId) {
|
|
|
134534
134503
|
}
|
|
134535
134504
|
function planFileExists(fallbackPlanFilePath) {
|
|
134536
134505
|
const planFilePath = permissionMode.getPlanFilePath() ?? fallbackPlanFilePath;
|
|
134537
|
-
return !!planFilePath &&
|
|
134506
|
+
return !!planFilePath && existsSync36(planFilePath);
|
|
134538
134507
|
}
|
|
134539
134508
|
function _readPlanFile(fallbackPlanFilePath) {
|
|
134540
134509
|
const planFilePath = permissionMode.getPlanFilePath() ?? fallbackPlanFilePath;
|
|
134541
134510
|
if (!planFilePath) {
|
|
134542
134511
|
return "No plan file path set.";
|
|
134543
134512
|
}
|
|
134544
|
-
if (!
|
|
134513
|
+
if (!existsSync36(planFilePath)) {
|
|
134545
134514
|
return `Plan file not found at ${planFilePath}`;
|
|
134546
134515
|
}
|
|
134547
134516
|
try {
|
|
134548
|
-
return
|
|
134517
|
+
return readFileSync20(planFilePath, "utf-8");
|
|
134549
134518
|
} catch {
|
|
134550
134519
|
return `Failed to read plan file at ${planFilePath}`;
|
|
134551
134520
|
}
|
|
@@ -134691,8 +134660,6 @@ function App2({
|
|
|
134691
134660
|
const lastRunIdRef = import_react103.useRef(null);
|
|
134692
134661
|
const resumeKey = useSuspend();
|
|
134693
134662
|
const pendingConversationSwitchRef = import_react103.useRef(null);
|
|
134694
|
-
const autoInitPendingAgentIdsRef = import_react103.useRef(new Set);
|
|
134695
|
-
const startupAutoInitConsumedRef = import_react103.useRef(false);
|
|
134696
134663
|
const prevInitialAgentIdRef = import_react103.useRef(initialAgentId);
|
|
134697
134664
|
const prevInitialAgentStateRef = import_react103.useRef(initialAgentState);
|
|
134698
134665
|
const prevInitialConversationIdRef = import_react103.useRef(initialConversationId);
|
|
@@ -135874,10 +135841,10 @@ function App2({
|
|
|
135874
135841
|
if (!planFilePath)
|
|
135875
135842
|
return;
|
|
135876
135843
|
try {
|
|
135877
|
-
const { readFileSync:
|
|
135878
|
-
if (!
|
|
135844
|
+
const { readFileSync: readFileSync21, existsSync: existsSync37 } = __require("node:fs");
|
|
135845
|
+
if (!existsSync37(planFilePath))
|
|
135879
135846
|
return;
|
|
135880
|
-
const planContent =
|
|
135847
|
+
const planContent = readFileSync21(planFilePath, "utf-8");
|
|
135881
135848
|
const previewItem = {
|
|
135882
135849
|
kind: "approval_preview",
|
|
135883
135850
|
id: `approval-preview-${toolCallId}`,
|
|
@@ -136289,9 +136256,9 @@ Memory may be stale. Try running: git -C ~/.letta/agents/${agentId}/memory pull`
|
|
|
136289
136256
|
(async () => {
|
|
136290
136257
|
try {
|
|
136291
136258
|
const { watch } = await import("node:fs");
|
|
136292
|
-
const { existsSync:
|
|
136259
|
+
const { existsSync: existsSync37 } = await import("node:fs");
|
|
136293
136260
|
const memRoot = getMemoryFilesystemRoot(agentId);
|
|
136294
|
-
if (!
|
|
136261
|
+
if (!existsSync37(memRoot))
|
|
136295
136262
|
return;
|
|
136296
136263
|
watcher = watch(memRoot, { recursive: true }, () => {});
|
|
136297
136264
|
memfsWatcherRef.current = watcher;
|
|
@@ -137450,7 +137417,7 @@ ${feedback}
|
|
|
137450
137417
|
buffersRef.current.interrupted = false;
|
|
137451
137418
|
continue;
|
|
137452
137419
|
}
|
|
137453
|
-
const retriable = await isRetriableError(stopReasonToHandle, lastRunId);
|
|
137420
|
+
const retriable = await isRetriableError(stopReasonToHandle, lastRunId, detailFromRun ?? latestErrorText ?? fallbackError);
|
|
137454
137421
|
if (retriable && llmApiErrorRetriesRef.current < LLM_API_ERROR_MAX_RETRIES3) {
|
|
137455
137422
|
llmApiErrorRetriesRef.current += 1;
|
|
137456
137423
|
const attempt = llmApiErrorRetriesRef.current;
|
|
@@ -138237,14 +138204,11 @@ ${feedback}
|
|
|
138237
138204
|
memoryPromptMode: willAutoEnableMemfs ? "memfs" : undefined
|
|
138238
138205
|
});
|
|
138239
138206
|
await enableMemfsIfCloud2(agent.id);
|
|
138240
|
-
if (settingsManager.isMemfsEnabled(agent.id)) {
|
|
138241
|
-
autoInitPendingAgentIdsRef.current.add(agent.id);
|
|
138242
|
-
}
|
|
138243
138207
|
await updateProjectSettings({ lastAgent: agent.id });
|
|
138244
138208
|
const targetConversationId = "default";
|
|
138245
138209
|
settingsManager.persistSession(agent.id, targetConversationId);
|
|
138246
138210
|
const agentUrl = buildChatUrl(agent.id);
|
|
138247
|
-
const memfsTip =
|
|
138211
|
+
const memfsTip = "Tip: use /init to initialize your agent's memory system!";
|
|
138248
138212
|
const successOutput = [
|
|
138249
138213
|
`Created **${agent.name || agent.id}** (use /pin to save)`,
|
|
138250
138214
|
`⎿ ${agentUrl}`,
|
|
@@ -138687,12 +138651,12 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
|
|
|
138687
138651
|
try {
|
|
138688
138652
|
const memoryRoot = getMemoryFilesystemRoot(agentId);
|
|
138689
138653
|
const personaCandidates = [
|
|
138690
|
-
|
|
138691
|
-
|
|
138654
|
+
join46(memoryRoot, "system", "persona.md"),
|
|
138655
|
+
join46(memoryRoot, "memory", "system", "persona.md")
|
|
138692
138656
|
];
|
|
138693
|
-
const personaPath = personaCandidates.find((candidate) =>
|
|
138657
|
+
const personaPath = personaCandidates.find((candidate) => existsSync36(candidate));
|
|
138694
138658
|
if (personaPath) {
|
|
138695
|
-
const personaContent =
|
|
138659
|
+
const personaContent = readFileSync20(personaPath, "utf-8");
|
|
138696
138660
|
setCurrentPersonalityId(detectPersonalityFromPersonaFile(personaContent));
|
|
138697
138661
|
} else {
|
|
138698
138662
|
setCurrentPersonalityId(null);
|
|
@@ -139988,11 +139952,11 @@ Path: ${result2.memoryDir}`, true, msg);
|
|
|
139988
139952
|
setCommandRunning(true);
|
|
139989
139953
|
try {
|
|
139990
139954
|
const memoryDir = getMemoryFilesystemRoot(agentId);
|
|
139991
|
-
if (!
|
|
139955
|
+
if (!existsSync36(memoryDir)) {
|
|
139992
139956
|
updateMemorySyncCommand(cmdId, "No local memory filesystem found to reset.", true, msg);
|
|
139993
139957
|
return { submitted: true };
|
|
139994
139958
|
}
|
|
139995
|
-
const backupDir =
|
|
139959
|
+
const backupDir = join46(tmpdir6(), `letta-memfs-reset-${agentId}-${Date.now()}`);
|
|
139996
139960
|
renameSync3(memoryDir, backupDir);
|
|
139997
139961
|
ensureMemoryFilesystemDirs(agentId);
|
|
139998
139962
|
updateMemorySyncCommand(cmdId, `Memory filesystem reset.
|
|
@@ -140020,8 +139984,8 @@ Run \`/memfs sync\` to repopulate from API.`, true, msg);
|
|
|
140020
139984
|
await removeGitMemoryTag2(agentId);
|
|
140021
139985
|
let backupInfo = "";
|
|
140022
139986
|
const memoryDir = getMemoryFilesystemRoot(agentId);
|
|
140023
|
-
if (
|
|
140024
|
-
const backupDir =
|
|
139987
|
+
if (existsSync36(memoryDir)) {
|
|
139988
|
+
const backupDir = join46(tmpdir6(), `letta-memfs-disable-${agentId}-${Date.now()}`);
|
|
140025
139989
|
renameSync3(memoryDir, backupDir);
|
|
140026
139990
|
backupInfo = `
|
|
140027
139991
|
Local files backed up to ${backupDir}`;
|
|
@@ -140191,7 +140155,6 @@ ${SYSTEM_REMINDER_CLOSE}`;
|
|
|
140191
140155
|
cmd.fail("Pending approval(s). Resolve approvals before running /init.");
|
|
140192
140156
|
return { submitted: false };
|
|
140193
140157
|
}
|
|
140194
|
-
autoInitPendingAgentIdsRef.current.delete(agentId);
|
|
140195
140158
|
setCommandRunning(true);
|
|
140196
140159
|
try {
|
|
140197
140160
|
cmd.finish("Building your memory palace... Start a new conversation with `letta --new` to work in parallel.", true);
|
|
@@ -140382,28 +140345,6 @@ ${SYSTEM_REMINDER_CLOSE}`),
|
|
|
140382
140345
|
return { submitted: true };
|
|
140383
140346
|
}
|
|
140384
140347
|
}
|
|
140385
|
-
if (autoInitPendingAgentIdsRef.current.has(agentId) && !isSystemOnly) {
|
|
140386
|
-
try {
|
|
140387
|
-
const fired = await fireAutoInit(agentId, async ({ success, error }) => {
|
|
140388
|
-
const msg2 = await handleMemorySubagentCompletion({
|
|
140389
|
-
agentId,
|
|
140390
|
-
conversationId: conversationIdRef.current,
|
|
140391
|
-
subagentType: "init",
|
|
140392
|
-
success,
|
|
140393
|
-
error
|
|
140394
|
-
}, {
|
|
140395
|
-
recompileByConversation: systemPromptRecompileByConversationRef.current,
|
|
140396
|
-
recompileQueuedByConversation: queuedSystemPromptRecompileByConversationRef.current,
|
|
140397
|
-
logRecompileFailure: (message2) => debugWarn("memory", message2)
|
|
140398
|
-
});
|
|
140399
|
-
appendTaskNotificationEvents([msg2]);
|
|
140400
|
-
});
|
|
140401
|
-
if (fired) {
|
|
140402
|
-
autoInitPendingAgentIdsRef.current.delete(agentId);
|
|
140403
|
-
sharedReminderStateRef.current.pendingAutoInitReminder = true;
|
|
140404
|
-
}
|
|
140405
|
-
} catch {}
|
|
140406
|
-
}
|
|
140407
140348
|
const contentParts = overrideContentParts ?? buildMessageContentFromDisplay(msg);
|
|
140408
140349
|
let ralphModeReminder = "";
|
|
140409
140350
|
if (ralphMode.getState().isActive) {
|
|
@@ -142445,7 +142386,7 @@ ${guidance}`);
|
|
|
142445
142386
|
}
|
|
142446
142387
|
if (mode === "bypassPermissions") {
|
|
142447
142388
|
const planFilePath = activePlanPath ?? fallbackPlanPath;
|
|
142448
|
-
const plansDir =
|
|
142389
|
+
const plansDir = join46(homedir36(), ".letta", "plans");
|
|
142449
142390
|
handlePlanKeepPlanning(`You must write your plan to a plan file before exiting plan mode.
|
|
142450
142391
|
` + (planFilePath ? `Plan file path: ${planFilePath}
|
|
142451
142392
|
` : "") + `Use a write tool to create your plan in ${plansDir}, then use ExitPlanMode to present the plan to the user.`);
|
|
@@ -142480,7 +142421,7 @@ ${guidance}`);
|
|
|
142480
142421
|
if (!hasUsablePlan) {
|
|
142481
142422
|
lastAutoHandledExitPlanToolCallIdRef.current = approval.toolCallId;
|
|
142482
142423
|
const planFilePath = activePlanPath ?? fallbackPlanPath;
|
|
142483
|
-
const plansDir =
|
|
142424
|
+
const plansDir = join46(homedir36(), ".letta", "plans");
|
|
142484
142425
|
handlePlanKeepPlanning(`You must write your plan to a plan file before exiting plan mode.
|
|
142485
142426
|
` + (planFilePath ? `Plan file path: ${planFilePath}
|
|
142486
142427
|
` : "") + `Use a write tool to create your plan in ${plansDir}, then use ExitPlanMode to present the plan to the user.`);
|
|
@@ -142712,14 +142653,6 @@ If using apply_patch, use this exact relative patch path: ${applyPatchRelativePa
|
|
|
142712
142653
|
return estimatedLiveHeight < resumeThreshold;
|
|
142713
142654
|
});
|
|
142714
142655
|
}, [estimatedLiveHeight, terminalRows]);
|
|
142715
|
-
import_react103.useEffect(() => {
|
|
142716
|
-
if (loadingState === "ready" && agentProvenance?.isNew && agentId && !startupAutoInitConsumedRef.current) {
|
|
142717
|
-
startupAutoInitConsumedRef.current = true;
|
|
142718
|
-
if (settingsManager.isMemfsEnabled(agentId)) {
|
|
142719
|
-
autoInitPendingAgentIdsRef.current.add(agentId);
|
|
142720
|
-
}
|
|
142721
|
-
}
|
|
142722
|
-
}, [loadingState, agentProvenance, agentId]);
|
|
142723
142656
|
import_react103.useEffect(() => {
|
|
142724
142657
|
if (loadingState === "ready" && !welcomeCommittedRef.current && messageHistory.length === 0) {
|
|
142725
142658
|
if (!continueSession && !agentProvenance) {
|
|
@@ -143712,6 +143645,7 @@ var init_App2 = __esm(async () => {
|
|
|
143712
143645
|
init_diff2();
|
|
143713
143646
|
init_errorContext();
|
|
143714
143647
|
init_errorFormatter();
|
|
143648
|
+
init_initCommand();
|
|
143715
143649
|
init_messageQueueBridge();
|
|
143716
143650
|
init_pasteRegistry();
|
|
143717
143651
|
init_planName();
|
|
@@ -143789,7 +143723,6 @@ var init_App2 = __esm(async () => {
|
|
|
143789
143723
|
init_accumulator(),
|
|
143790
143724
|
init_approvalClassification(),
|
|
143791
143725
|
init_formatArgsDisplay(),
|
|
143792
|
-
init_initCommand(),
|
|
143793
143726
|
init_memoryReminder(),
|
|
143794
143727
|
init_memorySubagentCompletion(),
|
|
143795
143728
|
init_reflectionTranscript(),
|
|
@@ -143887,13 +143820,13 @@ __export(exports_terminalKeybindingInstaller2, {
|
|
|
143887
143820
|
});
|
|
143888
143821
|
import {
|
|
143889
143822
|
copyFileSync as copyFileSync2,
|
|
143890
|
-
existsSync as
|
|
143823
|
+
existsSync as existsSync37,
|
|
143891
143824
|
mkdirSync as mkdirSync24,
|
|
143892
|
-
readFileSync as
|
|
143825
|
+
readFileSync as readFileSync21,
|
|
143893
143826
|
writeFileSync as writeFileSync19
|
|
143894
143827
|
} from "node:fs";
|
|
143895
143828
|
import { homedir as homedir37, platform as platform6 } from "node:os";
|
|
143896
|
-
import { dirname as dirname19, join as
|
|
143829
|
+
import { dirname as dirname19, join as join47 } from "node:path";
|
|
143897
143830
|
function detectTerminalType2() {
|
|
143898
143831
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
143899
143832
|
return "cursor";
|
|
@@ -143925,16 +143858,16 @@ function getKeybindingsPath2(terminal) {
|
|
|
143925
143858
|
}[terminal];
|
|
143926
143859
|
const os8 = platform6();
|
|
143927
143860
|
if (os8 === "darwin") {
|
|
143928
|
-
return
|
|
143861
|
+
return join47(homedir37(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
143929
143862
|
}
|
|
143930
143863
|
if (os8 === "win32") {
|
|
143931
143864
|
const appData = process.env.APPDATA;
|
|
143932
143865
|
if (!appData)
|
|
143933
143866
|
return null;
|
|
143934
|
-
return
|
|
143867
|
+
return join47(appData, appName, "User", "keybindings.json");
|
|
143935
143868
|
}
|
|
143936
143869
|
if (os8 === "linux") {
|
|
143937
|
-
return
|
|
143870
|
+
return join47(homedir37(), ".config", appName, "User", "keybindings.json");
|
|
143938
143871
|
}
|
|
143939
143872
|
return null;
|
|
143940
143873
|
}
|
|
@@ -143956,10 +143889,10 @@ function parseKeybindings2(content) {
|
|
|
143956
143889
|
}
|
|
143957
143890
|
}
|
|
143958
143891
|
function keybindingExists2(keybindingsPath) {
|
|
143959
|
-
if (!
|
|
143892
|
+
if (!existsSync37(keybindingsPath))
|
|
143960
143893
|
return false;
|
|
143961
143894
|
try {
|
|
143962
|
-
const content =
|
|
143895
|
+
const content = readFileSync21(keybindingsPath, { encoding: "utf-8" });
|
|
143963
143896
|
const keybindings = parseKeybindings2(content);
|
|
143964
143897
|
if (!keybindings)
|
|
143965
143898
|
return false;
|
|
@@ -143969,7 +143902,7 @@ function keybindingExists2(keybindingsPath) {
|
|
|
143969
143902
|
}
|
|
143970
143903
|
}
|
|
143971
143904
|
function createBackup2(keybindingsPath) {
|
|
143972
|
-
if (!
|
|
143905
|
+
if (!existsSync37(keybindingsPath))
|
|
143973
143906
|
return null;
|
|
143974
143907
|
const backupPath = `${keybindingsPath}.letta-backup`;
|
|
143975
143908
|
try {
|
|
@@ -143985,14 +143918,14 @@ function installKeybinding2(keybindingsPath) {
|
|
|
143985
143918
|
return { success: true, alreadyExists: true };
|
|
143986
143919
|
}
|
|
143987
143920
|
const parentDir = dirname19(keybindingsPath);
|
|
143988
|
-
if (!
|
|
143921
|
+
if (!existsSync37(parentDir)) {
|
|
143989
143922
|
mkdirSync24(parentDir, { recursive: true });
|
|
143990
143923
|
}
|
|
143991
143924
|
let keybindings = [];
|
|
143992
143925
|
let backupPath = null;
|
|
143993
|
-
if (
|
|
143926
|
+
if (existsSync37(keybindingsPath)) {
|
|
143994
143927
|
backupPath = createBackup2(keybindingsPath);
|
|
143995
|
-
const content =
|
|
143928
|
+
const content = readFileSync21(keybindingsPath, { encoding: "utf-8" });
|
|
143996
143929
|
const parsed = parseKeybindings2(content);
|
|
143997
143930
|
if (parsed === null) {
|
|
143998
143931
|
return {
|
|
@@ -144020,10 +143953,10 @@ function installKeybinding2(keybindingsPath) {
|
|
|
144020
143953
|
}
|
|
144021
143954
|
function removeKeybinding2(keybindingsPath) {
|
|
144022
143955
|
try {
|
|
144023
|
-
if (!
|
|
143956
|
+
if (!existsSync37(keybindingsPath)) {
|
|
144024
143957
|
return { success: true };
|
|
144025
143958
|
}
|
|
144026
|
-
const content =
|
|
143959
|
+
const content = readFileSync21(keybindingsPath, { encoding: "utf-8" });
|
|
144027
143960
|
const keybindings = parseKeybindings2(content);
|
|
144028
143961
|
if (!keybindings) {
|
|
144029
143962
|
return {
|
|
@@ -144087,20 +144020,20 @@ function getWezTermConfigPath2() {
|
|
|
144087
144020
|
}
|
|
144088
144021
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
144089
144022
|
if (xdgConfig) {
|
|
144090
|
-
const xdgPath =
|
|
144091
|
-
if (
|
|
144023
|
+
const xdgPath = join47(xdgConfig, "wezterm", "wezterm.lua");
|
|
144024
|
+
if (existsSync37(xdgPath))
|
|
144092
144025
|
return xdgPath;
|
|
144093
144026
|
}
|
|
144094
|
-
const configPath =
|
|
144095
|
-
if (
|
|
144027
|
+
const configPath = join47(homedir37(), ".config", "wezterm", "wezterm.lua");
|
|
144028
|
+
if (existsSync37(configPath))
|
|
144096
144029
|
return configPath;
|
|
144097
|
-
return
|
|
144030
|
+
return join47(homedir37(), ".wezterm.lua");
|
|
144098
144031
|
}
|
|
144099
144032
|
function wezTermDeleteFixExists2(configPath) {
|
|
144100
|
-
if (!
|
|
144033
|
+
if (!existsSync37(configPath))
|
|
144101
144034
|
return false;
|
|
144102
144035
|
try {
|
|
144103
|
-
const content =
|
|
144036
|
+
const content = readFileSync21(configPath, { encoding: "utf-8" });
|
|
144104
144037
|
return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
|
|
144105
144038
|
} catch {
|
|
144106
144039
|
return false;
|
|
@@ -144114,10 +144047,10 @@ function installWezTermDeleteFix2() {
|
|
|
144114
144047
|
}
|
|
144115
144048
|
let content = "";
|
|
144116
144049
|
let backupPath = null;
|
|
144117
|
-
if (
|
|
144050
|
+
if (existsSync37(configPath)) {
|
|
144118
144051
|
backupPath = `${configPath}.letta-backup`;
|
|
144119
144052
|
copyFileSync2(configPath, backupPath);
|
|
144120
|
-
content =
|
|
144053
|
+
content = readFileSync21(configPath, { encoding: "utf-8" });
|
|
144121
144054
|
}
|
|
144122
144055
|
if (content.includes("return {") && !content.includes("local config")) {
|
|
144123
144056
|
content = content.replace(/return\s*\{/, "local config = {");
|
|
@@ -144144,7 +144077,7 @@ ${WEZTERM_DELETE_FIX2}
|
|
|
144144
144077
|
`;
|
|
144145
144078
|
}
|
|
144146
144079
|
const parentDir = dirname19(configPath);
|
|
144147
|
-
if (!
|
|
144080
|
+
if (!existsSync37(parentDir)) {
|
|
144148
144081
|
mkdirSync24(parentDir, { recursive: true });
|
|
144149
144082
|
}
|
|
144150
144083
|
writeFileSync19(configPath, content, { encoding: "utf-8" });
|
|
@@ -144193,9 +144126,9 @@ __export(exports_settings2, {
|
|
|
144193
144126
|
getSetting: () => getSetting2
|
|
144194
144127
|
});
|
|
144195
144128
|
import { homedir as homedir38 } from "node:os";
|
|
144196
|
-
import { join as
|
|
144129
|
+
import { join as join48 } from "node:path";
|
|
144197
144130
|
function getSettingsPath2() {
|
|
144198
|
-
return
|
|
144131
|
+
return join48(homedir38(), ".letta", "settings.json");
|
|
144199
144132
|
}
|
|
144200
144133
|
async function loadSettings2() {
|
|
144201
144134
|
const settingsPath = getSettingsPath2();
|
|
@@ -144232,7 +144165,7 @@ async function getSetting2(key) {
|
|
|
144232
144165
|
return settings[key];
|
|
144233
144166
|
}
|
|
144234
144167
|
function getProjectSettingsPath2() {
|
|
144235
|
-
return
|
|
144168
|
+
return join48(process.cwd(), ".letta", "settings.local.json");
|
|
144236
144169
|
}
|
|
144237
144170
|
async function loadProjectSettings2() {
|
|
144238
144171
|
const settingsPath = getProjectSettingsPath2();
|
|
@@ -144250,7 +144183,7 @@ async function loadProjectSettings2() {
|
|
|
144250
144183
|
}
|
|
144251
144184
|
async function saveProjectSettings2(settings) {
|
|
144252
144185
|
const settingsPath = getProjectSettingsPath2();
|
|
144253
|
-
const dirPath =
|
|
144186
|
+
const dirPath = join48(process.cwd(), ".letta");
|
|
144254
144187
|
try {
|
|
144255
144188
|
if (!exists(dirPath)) {
|
|
144256
144189
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -144829,7 +144762,7 @@ function parseRegistryHandle2(handle) {
|
|
|
144829
144762
|
}
|
|
144830
144763
|
async function importAgentFromRegistry2(options) {
|
|
144831
144764
|
const { tmpdir: tmpdir7 } = await import("node:os");
|
|
144832
|
-
const { join:
|
|
144765
|
+
const { join: join49 } = await import("node:path");
|
|
144833
144766
|
const { writeFile: writeFile10, unlink: unlink3 } = await import("node:fs/promises");
|
|
144834
144767
|
const { author, name } = parseRegistryHandle2(options.handle);
|
|
144835
144768
|
const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER2}/${AGENT_REGISTRY_REPO2}/refs/heads/${AGENT_REGISTRY_BRANCH2}/agents/@${author}/${name}/${name}.af`;
|
|
@@ -144841,7 +144774,7 @@ async function importAgentFromRegistry2(options) {
|
|
|
144841
144774
|
throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
|
|
144842
144775
|
}
|
|
144843
144776
|
const afContent = await response.text();
|
|
144844
|
-
const tempPath =
|
|
144777
|
+
const tempPath = join49(tmpdir7(), `letta-import-${author}-${name}-${Date.now()}.af`);
|
|
144845
144778
|
await writeFile10(tempPath, afContent, "utf-8");
|
|
144846
144779
|
try {
|
|
144847
144780
|
const result = await importAgentFromFile2({
|
|
@@ -144885,22 +144818,22 @@ __export(exports_memoryFilesystem2, {
|
|
|
144885
144818
|
MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR2,
|
|
144886
144819
|
MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR2
|
|
144887
144820
|
});
|
|
144888
|
-
import { existsSync as
|
|
144821
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync25 } from "node:fs";
|
|
144889
144822
|
import { homedir as homedir39 } from "node:os";
|
|
144890
|
-
import { join as
|
|
144823
|
+
import { join as join49 } from "node:path";
|
|
144891
144824
|
function getMemoryFilesystemRoot2(agentId, homeDir = homedir39()) {
|
|
144892
|
-
return
|
|
144825
|
+
return join49(homeDir, MEMORY_FS_ROOT2, MEMORY_FS_AGENTS_DIR2, agentId, MEMORY_FS_MEMORY_DIR2);
|
|
144893
144826
|
}
|
|
144894
144827
|
function getMemorySystemDir2(agentId, homeDir = homedir39()) {
|
|
144895
|
-
return
|
|
144828
|
+
return join49(getMemoryFilesystemRoot2(agentId, homeDir), MEMORY_SYSTEM_DIR2);
|
|
144896
144829
|
}
|
|
144897
144830
|
function ensureMemoryFilesystemDirs2(agentId, homeDir = homedir39()) {
|
|
144898
144831
|
const root = getMemoryFilesystemRoot2(agentId, homeDir);
|
|
144899
144832
|
const systemDir = getMemorySystemDir2(agentId, homeDir);
|
|
144900
|
-
if (!
|
|
144833
|
+
if (!existsSync38(root)) {
|
|
144901
144834
|
mkdirSync25(root, { recursive: true });
|
|
144902
144835
|
}
|
|
144903
|
-
if (!
|
|
144836
|
+
if (!existsSync38(systemDir)) {
|
|
144904
144837
|
mkdirSync25(systemDir, { recursive: true });
|
|
144905
144838
|
}
|
|
144906
144839
|
}
|
|
@@ -147248,7 +147181,7 @@ Upgrade at: ${LETTA_USAGE_URL}
|
|
|
147248
147181
|
Delete ${resourceType} at: ${LETTA_AGENTS_URL}`;
|
|
147249
147182
|
}
|
|
147250
147183
|
if (isCreditExhaustedError(e, reasons)) {
|
|
147251
|
-
return `Your account
|
|
147184
|
+
return `Your account does not have credits for this model. Add your own API keys or upgrade your plan to purchase credits.`;
|
|
147252
147185
|
}
|
|
147253
147186
|
const tierUsageLimitMsg = getTierUsageLimitMessage(reasons);
|
|
147254
147187
|
if (tierUsageLimitMsg)
|
|
@@ -149538,10 +149471,10 @@ async function runListenSubcommand(argv) {
|
|
|
149538
149471
|
|
|
149539
149472
|
// src/cli/subcommands/memfs.ts
|
|
149540
149473
|
await init_memoryGit();
|
|
149541
|
-
import { cpSync, existsSync as
|
|
149474
|
+
import { cpSync, existsSync as existsSync21, mkdirSync as mkdirSync15, rmSync as rmSync3, statSync as statSync8 } from "node:fs";
|
|
149542
149475
|
import { readdir as readdir6 } from "node:fs/promises";
|
|
149543
149476
|
import { homedir as homedir23 } from "node:os";
|
|
149544
|
-
import { join as
|
|
149477
|
+
import { join as join27 } from "node:path";
|
|
149545
149478
|
import { parseArgs as parseArgs7 } from "node:util";
|
|
149546
149479
|
function printUsage4() {
|
|
149547
149480
|
console.log(`
|
|
@@ -149586,10 +149519,10 @@ function parseMemfsArgs(argv) {
|
|
|
149586
149519
|
});
|
|
149587
149520
|
}
|
|
149588
149521
|
function getMemoryRoot(agentId) {
|
|
149589
|
-
return
|
|
149522
|
+
return join27(homedir23(), ".letta", "agents", agentId, "memory");
|
|
149590
149523
|
}
|
|
149591
149524
|
function getAgentRoot(agentId) {
|
|
149592
|
-
return
|
|
149525
|
+
return join27(homedir23(), ".letta", "agents", agentId);
|
|
149593
149526
|
}
|
|
149594
149527
|
function formatBackupTimestamp(date = new Date) {
|
|
149595
149528
|
const pad = (value) => String(value).padStart(2, "0");
|
|
@@ -149603,7 +149536,7 @@ function formatBackupTimestamp(date = new Date) {
|
|
|
149603
149536
|
}
|
|
149604
149537
|
async function listBackups(agentId) {
|
|
149605
149538
|
const agentRoot = getAgentRoot(agentId);
|
|
149606
|
-
if (!
|
|
149539
|
+
if (!existsSync21(agentRoot)) {
|
|
149607
149540
|
return [];
|
|
149608
149541
|
}
|
|
149609
149542
|
const entries = await readdir6(agentRoot, { withFileTypes: true });
|
|
@@ -149613,7 +149546,7 @@ async function listBackups(agentId) {
|
|
|
149613
149546
|
continue;
|
|
149614
149547
|
if (!entry.name.startsWith("memory-backup-"))
|
|
149615
149548
|
continue;
|
|
149616
|
-
const path23 =
|
|
149549
|
+
const path23 = join27(agentRoot, entry.name);
|
|
149617
149550
|
let createdAt = null;
|
|
149618
149551
|
try {
|
|
149619
149552
|
const stat6 = statSync8(path23);
|
|
@@ -149630,7 +149563,7 @@ function resolveBackupPath(agentId, from) {
|
|
|
149630
149563
|
if (from.startsWith("/") || /^[A-Za-z]:[/\\]/.test(from)) {
|
|
149631
149564
|
return from;
|
|
149632
149565
|
}
|
|
149633
|
-
return
|
|
149566
|
+
return join27(getAgentRoot(agentId), from);
|
|
149634
149567
|
}
|
|
149635
149568
|
async function runMemfsSubcommand(argv) {
|
|
149636
149569
|
let parsed;
|
|
@@ -149690,14 +149623,14 @@ async function runMemfsSubcommand(argv) {
|
|
|
149690
149623
|
}
|
|
149691
149624
|
if (action === "backup") {
|
|
149692
149625
|
const root = getMemoryRoot(agentId);
|
|
149693
|
-
if (!
|
|
149626
|
+
if (!existsSync21(root)) {
|
|
149694
149627
|
console.error(`Memory directory not found for agent ${agentId}.`);
|
|
149695
149628
|
return 1;
|
|
149696
149629
|
}
|
|
149697
149630
|
const agentRoot = getAgentRoot(agentId);
|
|
149698
149631
|
const backupName = `memory-backup-${formatBackupTimestamp()}`;
|
|
149699
|
-
const backupPath =
|
|
149700
|
-
if (
|
|
149632
|
+
const backupPath = join27(agentRoot, backupName);
|
|
149633
|
+
if (existsSync21(backupPath)) {
|
|
149701
149634
|
console.error(`Backup already exists at ${backupPath}`);
|
|
149702
149635
|
return 1;
|
|
149703
149636
|
}
|
|
@@ -149721,7 +149654,7 @@ async function runMemfsSubcommand(argv) {
|
|
|
149721
149654
|
return 1;
|
|
149722
149655
|
}
|
|
149723
149656
|
const backupPath = resolveBackupPath(agentId, from);
|
|
149724
|
-
if (!
|
|
149657
|
+
if (!existsSync21(backupPath)) {
|
|
149725
149658
|
console.error(`Backup not found: ${backupPath}`);
|
|
149726
149659
|
return 1;
|
|
149727
149660
|
}
|
|
@@ -149743,11 +149676,11 @@ async function runMemfsSubcommand(argv) {
|
|
|
149743
149676
|
return 1;
|
|
149744
149677
|
}
|
|
149745
149678
|
const root = getMemoryRoot(agentId);
|
|
149746
|
-
if (!
|
|
149679
|
+
if (!existsSync21(root)) {
|
|
149747
149680
|
console.error(`Memory directory not found for agent ${agentId}.`);
|
|
149748
149681
|
return 1;
|
|
149749
149682
|
}
|
|
149750
|
-
if (
|
|
149683
|
+
if (existsSync21(out)) {
|
|
149751
149684
|
const stat6 = statSync8(out);
|
|
149752
149685
|
if (stat6.isDirectory()) {
|
|
149753
149686
|
const contents = await readdir6(out);
|
|
@@ -150142,7 +150075,7 @@ init_memoryScope();
|
|
|
150142
150075
|
init_readOnlyShell();
|
|
150143
150076
|
init_shell_command_normalization();
|
|
150144
150077
|
import { homedir as homedir24 } from "node:os";
|
|
150145
|
-
import { isAbsolute as isAbsolute17, join as
|
|
150078
|
+
import { isAbsolute as isAbsolute17, join as join28, relative as relative12 } from "node:path";
|
|
150146
150079
|
var MODE_KEY2 = Symbol.for("@letta/permissionMode");
|
|
150147
150080
|
var PLAN_FILE_KEY2 = Symbol.for("@letta/planFilePath");
|
|
150148
150081
|
var MODE_BEFORE_PLAN_KEY2 = Symbol.for("@letta/permissionModeBeforePlan");
|
|
@@ -150373,7 +150306,7 @@ class PermissionModeManager2 {
|
|
|
150373
150306
|
return "allow";
|
|
150374
150307
|
}
|
|
150375
150308
|
if (writeTools.includes(toolName)) {
|
|
150376
|
-
const plansDir =
|
|
150309
|
+
const plansDir = join28(homedir24(), ".letta", "plans");
|
|
150377
150310
|
const targetPath = toolArgs?.file_path || toolArgs?.path;
|
|
150378
150311
|
let candidatePaths = [];
|
|
150379
150312
|
if ((toolName === "ApplyPatch" || toolName === "apply_patch" || toolName === "memory_apply_patch") && toolArgs?.input) {
|
|
@@ -150424,7 +150357,7 @@ class PermissionModeManager2 {
|
|
|
150424
150357
|
}
|
|
150425
150358
|
const planWritePath = extractPlanFileWritePathFromShellCommand2(command);
|
|
150426
150359
|
if (planWritePath) {
|
|
150427
|
-
const plansDir =
|
|
150360
|
+
const plansDir = join28(homedir24(), ".letta", "plans");
|
|
150428
150361
|
const resolvedPath = resolvePlanTargetPath2(planWritePath, workingDirectory);
|
|
150429
150362
|
if (resolvedPath && isPathInPlansDir2(resolvedPath, plansDir)) {
|
|
150430
150363
|
return "allow";
|
|
@@ -150544,7 +150477,7 @@ await __promiseAll([
|
|
|
150544
150477
|
]);
|
|
150545
150478
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
150546
150479
|
import { homedir as homedir25 } from "node:os";
|
|
150547
|
-
import { join as
|
|
150480
|
+
import { join as join29, resolve as resolve24 } from "node:path";
|
|
150548
150481
|
var DEFAULT_SETTINGS3 = {
|
|
150549
150482
|
lastAgent: null,
|
|
150550
150483
|
tokenStreaming: false,
|
|
@@ -150931,7 +150864,7 @@ class SettingsManager2 {
|
|
|
150931
150864
|
return;
|
|
150932
150865
|
const settingsPath = this.getSettingsPath();
|
|
150933
150866
|
const home = process.env.HOME || homedir25();
|
|
150934
|
-
const dirPath =
|
|
150867
|
+
const dirPath = join29(home, ".letta");
|
|
150935
150868
|
try {
|
|
150936
150869
|
if (!exists(dirPath)) {
|
|
150937
150870
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -150970,7 +150903,7 @@ class SettingsManager2 {
|
|
|
150970
150903
|
if (!settings)
|
|
150971
150904
|
return;
|
|
150972
150905
|
const settingsPath = this.getProjectSettingsPath(workingDirectory);
|
|
150973
|
-
const dirPath =
|
|
150906
|
+
const dirPath = join29(workingDirectory, ".letta");
|
|
150974
150907
|
try {
|
|
150975
150908
|
let existingSettings = {};
|
|
150976
150909
|
if (exists(settingsPath)) {
|
|
@@ -150992,16 +150925,16 @@ class SettingsManager2 {
|
|
|
150992
150925
|
}
|
|
150993
150926
|
getSettingsPath() {
|
|
150994
150927
|
const home = process.env.HOME || homedir25();
|
|
150995
|
-
return
|
|
150928
|
+
return join29(home, ".letta", "settings.json");
|
|
150996
150929
|
}
|
|
150997
150930
|
getProjectSettingsPath(workingDirectory) {
|
|
150998
|
-
return
|
|
150931
|
+
return join29(workingDirectory, ".letta", "settings.json");
|
|
150999
150932
|
}
|
|
151000
150933
|
isProjectSettingsPathCollidingWithGlobal(workingDirectory) {
|
|
151001
150934
|
return resolve24(this.getProjectSettingsPath(workingDirectory)) === resolve24(this.getSettingsPath());
|
|
151002
150935
|
}
|
|
151003
150936
|
getLocalProjectSettingsPath(workingDirectory) {
|
|
151004
|
-
return
|
|
150937
|
+
return join29(workingDirectory, ".letta", "settings.local.json");
|
|
151005
150938
|
}
|
|
151006
150939
|
async loadLocalProjectSettings(workingDirectory = process.cwd()) {
|
|
151007
150940
|
const cached = this.localProjectSettings.get(workingDirectory);
|
|
@@ -151062,7 +150995,7 @@ class SettingsManager2 {
|
|
|
151062
150995
|
if (!settings)
|
|
151063
150996
|
return;
|
|
151064
150997
|
const settingsPath = this.getLocalProjectSettingsPath(workingDirectory);
|
|
151065
|
-
const dirPath =
|
|
150998
|
+
const dirPath = join29(workingDirectory, ".letta");
|
|
151066
150999
|
try {
|
|
151067
151000
|
if (!exists(dirPath)) {
|
|
151068
151001
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -151416,7 +151349,7 @@ class SettingsManager2 {
|
|
|
151416
151349
|
this.upsertAgentSettings(agentId, { systemPromptPreset: "" });
|
|
151417
151350
|
}
|
|
151418
151351
|
hasLocalLettaDir(workingDirectory = process.cwd()) {
|
|
151419
|
-
const dirPath =
|
|
151352
|
+
const dirPath = join29(workingDirectory, ".letta");
|
|
151420
151353
|
return exists(dirPath);
|
|
151421
151354
|
}
|
|
151422
151355
|
storeOAuthState(state, codeVerifier, redirectUri, provider) {
|
|
@@ -152271,12 +152204,12 @@ EXAMPLES
|
|
|
152271
152204
|
console.log(usage);
|
|
152272
152205
|
}
|
|
152273
152206
|
async function printInfo() {
|
|
152274
|
-
const { join:
|
|
152207
|
+
const { join: join50 } = await import("path");
|
|
152275
152208
|
const { getVersion: getVersion3 } = await Promise.resolve().then(() => (init_version2(), exports_version));
|
|
152276
152209
|
const { SKILLS_DIR: SKILLS_DIR3 } = await Promise.resolve().then(() => (init_skills2(), exports_skills2));
|
|
152277
152210
|
const { exists: exists3 } = await Promise.resolve().then(() => (init_fs2(), exports_fs));
|
|
152278
152211
|
const cwd2 = process.cwd();
|
|
152279
|
-
const skillsDir =
|
|
152212
|
+
const skillsDir = join50(cwd2, SKILLS_DIR3);
|
|
152280
152213
|
const skillsExist = exists3(skillsDir);
|
|
152281
152214
|
await settingsManager2.loadLocalProjectSettings(cwd2);
|
|
152282
152215
|
const localPinned = settingsManager2.getLocalPinnedAgents(cwd2);
|
|
@@ -152669,9 +152602,9 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
152669
152602
|
}
|
|
152670
152603
|
} else {
|
|
152671
152604
|
const { resolve: resolve32 } = await import("path");
|
|
152672
|
-
const { existsSync:
|
|
152605
|
+
const { existsSync: existsSync39 } = await import("fs");
|
|
152673
152606
|
const resolvedPath = resolve32(fromAfFile);
|
|
152674
|
-
if (!
|
|
152607
|
+
if (!existsSync39(resolvedPath)) {
|
|
152675
152608
|
console.error(`Error: AgentFile not found: ${resolvedPath}`);
|
|
152676
152609
|
process.exit(1);
|
|
152677
152610
|
}
|
|
@@ -153546,4 +153479,4 @@ Error during initialization: ${message}`);
|
|
|
153546
153479
|
}
|
|
153547
153480
|
main();
|
|
153548
153481
|
|
|
153549
|
-
//# debugId=
|
|
153482
|
+
//# debugId=CC952798FB2DAADB64756E2164756E21
|