@letta-ai/letta-code 0.21.15 → 0.21.17
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 +654 -586
- package/package.json +1 -1
- package/skills/working-in-parallel/SKILL.md +25 -10
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.17",
|
|
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 = {
|
|
@@ -9521,11 +9512,24 @@ var init_models2 = __esm(() => {
|
|
|
9521
9512
|
parallel_tool_calls: true
|
|
9522
9513
|
}
|
|
9523
9514
|
},
|
|
9515
|
+
{
|
|
9516
|
+
id: "glm-5.1",
|
|
9517
|
+
handle: "zai/glm-5.1",
|
|
9518
|
+
label: "GLM-5.1",
|
|
9519
|
+
description: "zAI's latest coding model",
|
|
9520
|
+
isFeatured: true,
|
|
9521
|
+
free: true,
|
|
9522
|
+
updateArgs: {
|
|
9523
|
+
context_window: 180000,
|
|
9524
|
+
max_output_tokens: 16000,
|
|
9525
|
+
parallel_tool_calls: true
|
|
9526
|
+
}
|
|
9527
|
+
},
|
|
9524
9528
|
{
|
|
9525
9529
|
id: "glm-5",
|
|
9526
9530
|
handle: "zai/glm-5",
|
|
9527
9531
|
label: "GLM-5",
|
|
9528
|
-
description: "zAI's latest coding model",
|
|
9532
|
+
description: "zAI's latest coding model (legacy)",
|
|
9529
9533
|
isFeatured: true,
|
|
9530
9534
|
free: true,
|
|
9531
9535
|
updateArgs: {
|
|
@@ -37969,13 +37973,17 @@ async function updateAgentLLMConfig2(agentId, modelHandle, updateArgs, options)
|
|
|
37969
37973
|
const finalAgent = await client.agents.retrieve(agentId);
|
|
37970
37974
|
return finalAgent;
|
|
37971
37975
|
}
|
|
37972
|
-
async function updateConversationLLMConfig(conversationId, modelHandle, updateArgs) {
|
|
37976
|
+
async function updateConversationLLMConfig(conversationId, modelHandle, updateArgs, options) {
|
|
37973
37977
|
const client = await getClient();
|
|
37974
37978
|
const modelSettings = buildModelSettings2(modelHandle, updateArgs);
|
|
37979
|
+
const explicitContextWindow = updateArgs?.context_window;
|
|
37980
|
+
const shouldPreserveContextWindow = options?.preserveContextWindow === true;
|
|
37981
|
+
const contextWindow = explicitContextWindow ?? (!shouldPreserveContextWindow ? await getModelContextWindow(modelHandle) : undefined);
|
|
37975
37982
|
const hasModelSettings = Object.keys(modelSettings).length > 0;
|
|
37976
37983
|
const payload = {
|
|
37977
37984
|
model: modelHandle,
|
|
37978
|
-
...hasModelSettings && { model_settings: modelSettings }
|
|
37985
|
+
...hasModelSettings && { model_settings: modelSettings },
|
|
37986
|
+
...contextWindow && { context_window_limit: contextWindow }
|
|
37979
37987
|
};
|
|
37980
37988
|
return client.conversations.update(conversationId, payload);
|
|
37981
37989
|
}
|
|
@@ -38086,7 +38094,8 @@ var init_modify = __esm(async () => {
|
|
|
38086
38094
|
var exports_create = {};
|
|
38087
38095
|
__export(exports_create, {
|
|
38088
38096
|
createAgentWithBaseToolsRecovery: () => createAgentWithBaseToolsRecovery,
|
|
38089
|
-
createAgent: () => createAgent
|
|
38097
|
+
createAgent: () => createAgent,
|
|
38098
|
+
addBaseToolsToServer: () => addBaseToolsToServer
|
|
38090
38099
|
});
|
|
38091
38100
|
function isToolsNotFoundError(err) {
|
|
38092
38101
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -38319,9 +38328,13 @@ __export(exports_memoryGit, {
|
|
|
38319
38328
|
pushMemory: () => pushMemory,
|
|
38320
38329
|
pullMemory: () => pullMemory,
|
|
38321
38330
|
normalizeCredentialBaseUrl: () => normalizeCredentialBaseUrl,
|
|
38331
|
+
maybeUpdateMemoryRemoteOrigin: () => maybeUpdateMemoryRemoteOrigin,
|
|
38332
|
+
isRetryableGitTransientError: () => isRetryableGitTransientError,
|
|
38333
|
+
isMemfsRemoteUrlForAgent: () => isMemfsRemoteUrlForAgent,
|
|
38322
38334
|
isGitRepo: () => isGitRepo,
|
|
38323
38335
|
getMemoryRepoDir: () => getMemoryRepoDir,
|
|
38324
38336
|
getMemoryGitStatus: () => getMemoryGitStatus,
|
|
38337
|
+
getGitRemoteUrl: () => getGitRemoteUrl,
|
|
38325
38338
|
getAgentRootDir: () => getAgentRootDir,
|
|
38326
38339
|
cloneMemoryRepo: () => cloneMemoryRepo,
|
|
38327
38340
|
addGitMemoryTag: () => addGitMemoryTag,
|
|
@@ -38355,9 +38368,45 @@ function normalizeCredentialBaseUrl(serverUrl) {
|
|
|
38355
38368
|
return trimmed;
|
|
38356
38369
|
}
|
|
38357
38370
|
}
|
|
38358
|
-
function
|
|
38359
|
-
|
|
38360
|
-
|
|
38371
|
+
function normalizeRemoteUrl(url) {
|
|
38372
|
+
return url.trim().replace(/\/+$/, "");
|
|
38373
|
+
}
|
|
38374
|
+
function escapeRegex(value) {
|
|
38375
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
38376
|
+
}
|
|
38377
|
+
function isMemfsRemoteUrlForAgent(remoteUrl, agentId) {
|
|
38378
|
+
const normalized = normalizeRemoteUrl(remoteUrl);
|
|
38379
|
+
const escapedAgentId = escapeRegex(agentId);
|
|
38380
|
+
return new RegExp(`^https?://[^\\s]+/v1/git/${escapedAgentId}/state\\.git$`, "i").test(normalized);
|
|
38381
|
+
}
|
|
38382
|
+
function getGitRemoteUrl(agentId, baseUrl) {
|
|
38383
|
+
const resolvedBaseUrl = (baseUrl ?? getServerUrl()).trim().replace(/\/+$/, "");
|
|
38384
|
+
return `${resolvedBaseUrl}/v1/git/${agentId}/state.git`;
|
|
38385
|
+
}
|
|
38386
|
+
async function maybeUpdateMemoryRemoteOrigin(repoDir, agentId) {
|
|
38387
|
+
let currentOrigin = "";
|
|
38388
|
+
try {
|
|
38389
|
+
const { stdout } = await runGit(repoDir, ["remote", "get-url", "origin"]);
|
|
38390
|
+
currentOrigin = stdout.trim();
|
|
38391
|
+
} catch {
|
|
38392
|
+
return;
|
|
38393
|
+
}
|
|
38394
|
+
if (!currentOrigin) {
|
|
38395
|
+
return;
|
|
38396
|
+
}
|
|
38397
|
+
if (!isMemfsRemoteUrlForAgent(currentOrigin, agentId)) {
|
|
38398
|
+
return;
|
|
38399
|
+
}
|
|
38400
|
+
const expectedOrigin = normalizeRemoteUrl(getGitRemoteUrl(agentId));
|
|
38401
|
+
const normalizedCurrent = normalizeRemoteUrl(currentOrigin);
|
|
38402
|
+
if (normalizedCurrent === expectedOrigin) {
|
|
38403
|
+
return;
|
|
38404
|
+
}
|
|
38405
|
+
await runGit(repoDir, ["remote", "set-url", "origin", expectedOrigin]);
|
|
38406
|
+
debugLog("memfs-git", `Updated origin remote for ${agentId}: ${normalizedCurrent} -> ${expectedOrigin}`);
|
|
38407
|
+
}
|
|
38408
|
+
function getMemoryRemoteUrl(agentId) {
|
|
38409
|
+
return getGitRemoteUrl(agentId);
|
|
38361
38410
|
}
|
|
38362
38411
|
async function getAuthToken() {
|
|
38363
38412
|
const client = await getClient();
|
|
@@ -38381,6 +38430,35 @@ async function runGit(cwd2, args, token) {
|
|
|
38381
38430
|
stderr: result.stderr?.toString() ?? ""
|
|
38382
38431
|
};
|
|
38383
38432
|
}
|
|
38433
|
+
function isRetryableGitTransientError(error) {
|
|
38434
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
38435
|
+
if (RETRYABLE_GIT_HTTP_ERROR_RE.test(message)) {
|
|
38436
|
+
return true;
|
|
38437
|
+
}
|
|
38438
|
+
if (message.includes("RPC failed") && RETRYABLE_GIT_NETWORK_ERROR_RE.test(message)) {
|
|
38439
|
+
return true;
|
|
38440
|
+
}
|
|
38441
|
+
return false;
|
|
38442
|
+
}
|
|
38443
|
+
async function runGitWithRetry(cwd2, args, token, options) {
|
|
38444
|
+
const attempts = options?.attempts ?? 3;
|
|
38445
|
+
const baseDelayMs = options?.baseDelayMs ?? 500;
|
|
38446
|
+
const operation = options?.operation ?? args[0] ?? "git op";
|
|
38447
|
+
for (let attempt = 1;attempt <= attempts; attempt += 1) {
|
|
38448
|
+
try {
|
|
38449
|
+
return await runGit(cwd2, args, token);
|
|
38450
|
+
} catch (error) {
|
|
38451
|
+
if (!isRetryableGitTransientError(error) || attempt >= attempts) {
|
|
38452
|
+
throw error;
|
|
38453
|
+
}
|
|
38454
|
+
const delayMs = baseDelayMs * 2 ** (attempt - 1);
|
|
38455
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
38456
|
+
debugWarn("memfs-git", `${operation} failed with transient error (attempt ${attempt}/${attempts}): ${msg}. Retrying in ${delayMs}ms`);
|
|
38457
|
+
await new Promise((resolve2) => setTimeout(resolve2, delayMs));
|
|
38458
|
+
}
|
|
38459
|
+
}
|
|
38460
|
+
throw new Error(`Unexpected retry loop exit for ${operation}`);
|
|
38461
|
+
}
|
|
38384
38462
|
async function configureLocalCredentialHelper(dir, token) {
|
|
38385
38463
|
const rawBaseUrl = getServerUrl();
|
|
38386
38464
|
const normalizedBaseUrl = normalizeCredentialBaseUrl(rawBaseUrl);
|
|
@@ -38410,12 +38488,14 @@ function isGitRepo(agentId) {
|
|
|
38410
38488
|
}
|
|
38411
38489
|
async function cloneMemoryRepo(agentId) {
|
|
38412
38490
|
const token = await getAuthToken();
|
|
38413
|
-
const url =
|
|
38491
|
+
const url = getMemoryRemoteUrl(agentId);
|
|
38414
38492
|
const dir = getMemoryRepoDir(agentId);
|
|
38415
38493
|
debugLog("memfs-git", `Cloning ${url} → ${dir}`);
|
|
38416
38494
|
if (!existsSync8(dir)) {
|
|
38417
38495
|
mkdirSync6(dir, { recursive: true });
|
|
38418
|
-
await
|
|
38496
|
+
await runGitWithRetry(dir, ["clone", url, "."], token, {
|
|
38497
|
+
operation: "clone memory repo"
|
|
38498
|
+
});
|
|
38419
38499
|
} else if (!existsSync8(join7(dir, ".git"))) {
|
|
38420
38500
|
const tmpDir = `${dir}-git-clone-tmp`;
|
|
38421
38501
|
try {
|
|
@@ -38423,7 +38503,9 @@ async function cloneMemoryRepo(agentId) {
|
|
|
38423
38503
|
rmSync(tmpDir, { recursive: true, force: true });
|
|
38424
38504
|
}
|
|
38425
38505
|
mkdirSync6(tmpDir, { recursive: true });
|
|
38426
|
-
await
|
|
38506
|
+
await runGitWithRetry(tmpDir, ["clone", url, "."], token, {
|
|
38507
|
+
operation: "clone memory repo (tmp migration)"
|
|
38508
|
+
});
|
|
38427
38509
|
renameSync(join7(tmpDir, ".git"), join7(dir, ".git"));
|
|
38428
38510
|
await runGit(dir, ["checkout", "--", "."], token);
|
|
38429
38511
|
debugLog("memfs-git", "Migrated existing memory directory to git repo");
|
|
@@ -38439,10 +38521,11 @@ async function cloneMemoryRepo(agentId) {
|
|
|
38439
38521
|
async function pullMemory(agentId) {
|
|
38440
38522
|
const token = await getAuthToken();
|
|
38441
38523
|
const dir = getMemoryRepoDir(agentId);
|
|
38524
|
+
await maybeUpdateMemoryRemoteOrigin(dir, agentId);
|
|
38442
38525
|
await configureLocalCredentialHelper(dir, token);
|
|
38443
38526
|
installPreCommitHook(dir);
|
|
38444
38527
|
try {
|
|
38445
|
-
const { stdout, stderr } = await
|
|
38528
|
+
const { stdout, stderr } = await runGitWithRetry(dir, ["pull", "--ff-only"], token, { operation: "pull --ff-only" });
|
|
38446
38529
|
const output = stdout + stderr;
|
|
38447
38530
|
const updated = !output.includes("Already up to date");
|
|
38448
38531
|
return {
|
|
@@ -38452,7 +38535,7 @@ async function pullMemory(agentId) {
|
|
|
38452
38535
|
} catch {
|
|
38453
38536
|
debugWarn("memfs-git", "Fast-forward pull failed, trying rebase");
|
|
38454
38537
|
try {
|
|
38455
|
-
const { stdout, stderr } = await
|
|
38538
|
+
const { stdout, stderr } = await runGitWithRetry(dir, ["pull", "--rebase"], token, { operation: "pull --rebase" });
|
|
38456
38539
|
return { updated: true, summary: (stdout + stderr).trim() };
|
|
38457
38540
|
} catch (rebaseErr) {
|
|
38458
38541
|
const msg = rebaseErr instanceof Error ? rebaseErr.message : String(rebaseErr);
|
|
@@ -38470,6 +38553,7 @@ Hint: verify remote and auth:
|
|
|
38470
38553
|
async function pushMemory(agentId) {
|
|
38471
38554
|
const token = await getAuthToken();
|
|
38472
38555
|
const dir = getMemoryRepoDir(agentId);
|
|
38556
|
+
await maybeUpdateMemoryRemoteOrigin(dir, agentId);
|
|
38473
38557
|
await configureLocalCredentialHelper(dir, token);
|
|
38474
38558
|
try {
|
|
38475
38559
|
await runGit(dir, ["push"], token);
|
|
@@ -38548,7 +38632,7 @@ async function removeGitMemoryTag(agentId) {
|
|
|
38548
38632
|
debugWarn("memfs-git", `Failed to remove git-memory tag: ${err instanceof Error ? err.message : String(err)}`);
|
|
38549
38633
|
}
|
|
38550
38634
|
}
|
|
38551
|
-
var execFile, GIT_MEMORY_ENABLED_TAG = "git-memory-enabled", PRE_COMMIT_HOOK_SCRIPT = `#!/usr/bin/env bash
|
|
38635
|
+
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
38636
|
# Validate frontmatter in staged memory .md files
|
|
38553
38637
|
# Installed by Letta Code CLI
|
|
38554
38638
|
|
|
@@ -38686,6 +38770,8 @@ var init_memoryGit = __esm(async () => {
|
|
|
38686
38770
|
init_debug();
|
|
38687
38771
|
await init_client2();
|
|
38688
38772
|
execFile = promisify(execFileCb);
|
|
38773
|
+
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;
|
|
38774
|
+
RETRYABLE_GIT_NETWORK_ERROR_RE = /(remote end hung up unexpectedly|connection reset by peer|operation timed out|timed out)/i;
|
|
38689
38775
|
});
|
|
38690
38776
|
|
|
38691
38777
|
// src/agent/personality.ts
|
|
@@ -38877,7 +38963,7 @@ async function buildCreateAgentOptionsForPersonality(params) {
|
|
|
38877
38963
|
return {
|
|
38878
38964
|
name: name ?? personality.label,
|
|
38879
38965
|
description: description ?? personality.description,
|
|
38880
|
-
model,
|
|
38966
|
+
model: model ?? personality.defaultModel,
|
|
38881
38967
|
tags,
|
|
38882
38968
|
memoryPromptMode: "memfs",
|
|
38883
38969
|
memoryBlocks: defaultMemoryBlocks.map((block) => {
|
|
@@ -39085,7 +39171,8 @@ var init_personality = __esm(async () => {
|
|
|
39085
39171
|
{
|
|
39086
39172
|
id: "kawaii",
|
|
39087
39173
|
label: "Letta-Chan",
|
|
39088
|
-
description: "sugoi~ (◕‿◕)✨"
|
|
39174
|
+
description: "sugoi~ (◕‿◕)✨",
|
|
39175
|
+
defaultModel: "auto-chat"
|
|
39089
39176
|
},
|
|
39090
39177
|
{
|
|
39091
39178
|
id: "claude",
|
|
@@ -53503,6 +53590,7 @@ class PermissionModeManager {
|
|
|
53503
53590
|
"Edit",
|
|
53504
53591
|
"MultiEdit",
|
|
53505
53592
|
"NotebookEdit",
|
|
53593
|
+
"memory",
|
|
53506
53594
|
"apply_patch",
|
|
53507
53595
|
"ApplyPatch",
|
|
53508
53596
|
"memory_apply_patch",
|
|
@@ -56112,6 +56200,20 @@ __export(exports_Bash, {
|
|
|
56112
56200
|
bash: () => bash
|
|
56113
56201
|
});
|
|
56114
56202
|
import { spawn as spawn3 } from "node:child_process";
|
|
56203
|
+
import { resolve as resolve7 } from "node:path";
|
|
56204
|
+
function validateWorktreePath(command, cwd2) {
|
|
56205
|
+
const match = command.match(/\bgit\s+worktree\s+add\s+(?:-b\s+\S+\s+)?(\S+)/);
|
|
56206
|
+
if (!match?.[1])
|
|
56207
|
+
return null;
|
|
56208
|
+
const targetPath = match[1];
|
|
56209
|
+
const resolved = resolve7(cwd2, targetPath);
|
|
56210
|
+
const requiredPrefix = resolve7(cwd2, ".letta/worktrees");
|
|
56211
|
+
if (!resolved.startsWith(requiredPrefix)) {
|
|
56212
|
+
return `Error: Worktrees must be created under .letta/worktrees/. ` + `Use: git worktree add -b <branch> .letta/worktrees/<name> main
|
|
56213
|
+
` + `Got: ${targetPath}`;
|
|
56214
|
+
}
|
|
56215
|
+
return null;
|
|
56216
|
+
}
|
|
56115
56217
|
function getBackgroundLauncher(command) {
|
|
56116
56218
|
if (cachedWorkingLauncher) {
|
|
56117
56219
|
const [executable, ...launcherArgs] = cachedWorkingLauncher;
|
|
@@ -56197,6 +56299,13 @@ async function bash(args) {
|
|
|
56197
56299
|
onOutput
|
|
56198
56300
|
} = args;
|
|
56199
56301
|
const userCwd = process.env.USER_CWD || process.cwd();
|
|
56302
|
+
const worktreeError = validateWorktreePath(command, userCwd);
|
|
56303
|
+
if (worktreeError) {
|
|
56304
|
+
return {
|
|
56305
|
+
content: [{ type: "text", text: worktreeError }],
|
|
56306
|
+
status: "error"
|
|
56307
|
+
};
|
|
56308
|
+
}
|
|
56200
56309
|
if (command === "/bg") {
|
|
56201
56310
|
const processes = Array.from(backgroundProcesses.entries());
|
|
56202
56311
|
if (processes.length === 0) {
|
|
@@ -56383,7 +56492,7 @@ var init_Bash2 = __esm(async () => {
|
|
|
56383
56492
|
// src/tools/impl/BashOutput.ts
|
|
56384
56493
|
import { readFileSync as readFileSync10, statSync as statSync5 } from "node:fs";
|
|
56385
56494
|
function sleep2(ms) {
|
|
56386
|
-
return new Promise((
|
|
56495
|
+
return new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
56387
56496
|
}
|
|
56388
56497
|
function readOutputFile(filePath) {
|
|
56389
56498
|
if (!filePath) {
|
|
@@ -57365,12 +57474,12 @@ var init_LS2 = __esm(() => {
|
|
|
57365
57474
|
|
|
57366
57475
|
// src/tools/impl/LS.ts
|
|
57367
57476
|
import { readdir as readdir2, stat } from "node:fs/promises";
|
|
57368
|
-
import { join as join18, resolve as
|
|
57477
|
+
import { join as join18, resolve as resolve12 } from "node:path";
|
|
57369
57478
|
async function ls(args) {
|
|
57370
57479
|
validateRequiredParams(args, ["path"], "LS");
|
|
57371
57480
|
validateParamTypes(args, LS_default2, "LS");
|
|
57372
57481
|
const { path: inputPath, ignore = [] } = args;
|
|
57373
|
-
const dirPath =
|
|
57482
|
+
const dirPath = resolve12(inputPath);
|
|
57374
57483
|
try {
|
|
57375
57484
|
const items = await readdir2(dirPath);
|
|
57376
57485
|
const filteredItems = items.filter((item) => !ignore.some((pattern) => import_picomatch2.default.isMatch(item, pattern)));
|
|
@@ -57464,7 +57573,6 @@ function createSharedReminderState() {
|
|
|
57464
57573
|
lastNotifiedPermissionMode: null,
|
|
57465
57574
|
turnCount: 0,
|
|
57466
57575
|
pendingReflectionTrigger: false,
|
|
57467
|
-
pendingAutoInitReminder: false,
|
|
57468
57576
|
pendingCommandIoReminders: [],
|
|
57469
57577
|
pendingToolsetChangeReminders: []
|
|
57470
57578
|
};
|
|
@@ -57804,7 +57912,7 @@ import {
|
|
|
57804
57912
|
writeFile as writeFile2
|
|
57805
57913
|
} from "node:fs/promises";
|
|
57806
57914
|
import { homedir as homedir15 } from "node:os";
|
|
57807
|
-
import { dirname as dirname7, isAbsolute as isAbsolute9, relative as relative5, resolve as
|
|
57915
|
+
import { dirname as dirname7, isAbsolute as isAbsolute9, relative as relative5, resolve as resolve13 } from "node:path";
|
|
57808
57916
|
import { promisify as promisify10 } from "node:util";
|
|
57809
57917
|
async function getAgentIdentity() {
|
|
57810
57918
|
const envAgentId = (process.env.AGENT_ID || process.env.LETTA_AGENT_ID || "").trim();
|
|
@@ -57959,7 +58067,7 @@ async function memory(args) {
|
|
|
57959
58067
|
function resolveMemoryDir() {
|
|
57960
58068
|
const direct = process.env.MEMORY_DIR || process.env.LETTA_MEMORY_DIR;
|
|
57961
58069
|
if (direct && direct.trim().length > 0) {
|
|
57962
|
-
return
|
|
58070
|
+
return resolve13(direct);
|
|
57963
58071
|
}
|
|
57964
58072
|
const contextAgentId = (() => {
|
|
57965
58073
|
try {
|
|
@@ -57970,7 +58078,7 @@ function resolveMemoryDir() {
|
|
|
57970
58078
|
})();
|
|
57971
58079
|
const agentId = contextAgentId || (process.env.AGENT_ID || process.env.LETTA_AGENT_ID || "").trim();
|
|
57972
58080
|
if (agentId && agentId.trim().length > 0) {
|
|
57973
|
-
return
|
|
58081
|
+
return resolve13(homedir15(), ".letta", "agents", agentId, "memory");
|
|
57974
58082
|
}
|
|
57975
58083
|
throw new Error("memory: unable to resolve memory directory. Ensure MEMORY_DIR (or AGENT_ID) is available.");
|
|
57976
58084
|
}
|
|
@@ -57978,7 +58086,7 @@ function ensureMemoryRepo(memoryDir) {
|
|
|
57978
58086
|
if (!existsSync14(memoryDir)) {
|
|
57979
58087
|
throw new Error(`memory: memory directory does not exist: ${memoryDir}`);
|
|
57980
58088
|
}
|
|
57981
|
-
if (!existsSync14(
|
|
58089
|
+
if (!existsSync14(resolve13(memoryDir, ".git"))) {
|
|
57982
58090
|
throw new Error(`memory: ${memoryDir} is not a git repository. This tool requires a git-backed memory filesystem.`);
|
|
57983
58091
|
}
|
|
57984
58092
|
}
|
|
@@ -57992,7 +58100,7 @@ function normalizeMemoryLabel(memoryDir, inputPath, fieldName) {
|
|
|
57992
58100
|
}
|
|
57993
58101
|
const isWindowsAbsolute = /^[a-zA-Z]:[\\/]/.test(raw);
|
|
57994
58102
|
if (isAbsolute9(raw) || isWindowsAbsolute) {
|
|
57995
|
-
const absolutePath =
|
|
58103
|
+
const absolutePath = resolve13(raw);
|
|
57996
58104
|
const relToMemory = relative5(memoryDir, absolutePath);
|
|
57997
58105
|
if (relToMemory && !relToMemory.startsWith("..") && !isAbsolute9(relToMemory)) {
|
|
57998
58106
|
return normalizeRelativeMemoryLabel(relToMemory, fieldName);
|
|
@@ -58038,7 +58146,7 @@ function resolveMemoryFilePath(memoryDir, label) {
|
|
|
58038
58146
|
return absolute;
|
|
58039
58147
|
}
|
|
58040
58148
|
function resolveMemoryPath(memoryDir, path11) {
|
|
58041
|
-
const absolute =
|
|
58149
|
+
const absolute = resolve13(memoryDir, path11);
|
|
58042
58150
|
const rel = relative5(memoryDir, absolute);
|
|
58043
58151
|
if (rel.startsWith("..") || isAbsolute9(rel)) {
|
|
58044
58152
|
throw new Error("memory: resolved path escapes memory directory");
|
|
@@ -58167,6 +58275,7 @@ async function commitAndPush(memoryDir, pathspecs, reason) {
|
|
|
58167
58275
|
]);
|
|
58168
58276
|
const head = await runGit4(memoryDir, ["rev-parse", "HEAD"]);
|
|
58169
58277
|
const sha = head.stdout.trim();
|
|
58278
|
+
await maybeUpdateMemoryRemoteOrigin(memoryDir, agentId);
|
|
58170
58279
|
try {
|
|
58171
58280
|
await runGit4(memoryDir, ["push"]);
|
|
58172
58281
|
} catch (error) {
|
|
@@ -58202,7 +58311,10 @@ function emitMemoryUpdated(affectedPaths) {
|
|
|
58202
58311
|
var execFile10;
|
|
58203
58312
|
var init_Memory2 = __esm(async () => {
|
|
58204
58313
|
init_context();
|
|
58205
|
-
await
|
|
58314
|
+
await __promiseAll([
|
|
58315
|
+
init_client2(),
|
|
58316
|
+
init_memoryGit()
|
|
58317
|
+
]);
|
|
58206
58318
|
execFile10 = promisify10(execFileCb3);
|
|
58207
58319
|
});
|
|
58208
58320
|
|
|
@@ -58219,7 +58331,7 @@ import {
|
|
|
58219
58331
|
writeFile as writeFile3
|
|
58220
58332
|
} from "node:fs/promises";
|
|
58221
58333
|
import { homedir as homedir16 } from "node:os";
|
|
58222
|
-
import { dirname as dirname8, isAbsolute as isAbsolute10, relative as relative6, resolve as
|
|
58334
|
+
import { dirname as dirname8, isAbsolute as isAbsolute10, relative as relative6, resolve as resolve14 } from "node:path";
|
|
58223
58335
|
import { promisify as promisify11 } from "node:util";
|
|
58224
58336
|
async function getAgentIdentity2() {
|
|
58225
58337
|
const envAgentId = (process.env.AGENT_ID || process.env.LETTA_AGENT_ID || "").trim();
|
|
@@ -58495,7 +58607,7 @@ function normalizeAddedContent(label, rawContent) {
|
|
|
58495
58607
|
function resolveMemoryDir2() {
|
|
58496
58608
|
const direct = process.env.MEMORY_DIR || process.env.LETTA_MEMORY_DIR;
|
|
58497
58609
|
if (direct && direct.trim().length > 0) {
|
|
58498
|
-
return
|
|
58610
|
+
return resolve14(direct);
|
|
58499
58611
|
}
|
|
58500
58612
|
const contextAgentId = (() => {
|
|
58501
58613
|
try {
|
|
@@ -58506,7 +58618,7 @@ function resolveMemoryDir2() {
|
|
|
58506
58618
|
})();
|
|
58507
58619
|
const agentId = contextAgentId || (process.env.AGENT_ID || process.env.LETTA_AGENT_ID || "").trim();
|
|
58508
58620
|
if (agentId && agentId.trim().length > 0) {
|
|
58509
|
-
return
|
|
58621
|
+
return resolve14(homedir16(), ".letta", "agents", agentId, "memory");
|
|
58510
58622
|
}
|
|
58511
58623
|
throw new Error("memory_apply_patch: unable to resolve memory directory. Ensure MEMORY_DIR (or AGENT_ID) is available.");
|
|
58512
58624
|
}
|
|
@@ -58514,7 +58626,7 @@ function ensureMemoryRepo2(memoryDir) {
|
|
|
58514
58626
|
if (!existsSync15(memoryDir)) {
|
|
58515
58627
|
throw new Error(`memory_apply_patch: memory directory does not exist: ${memoryDir}`);
|
|
58516
58628
|
}
|
|
58517
|
-
if (!existsSync15(
|
|
58629
|
+
if (!existsSync15(resolve14(memoryDir, ".git"))) {
|
|
58518
58630
|
throw new Error(`memory_apply_patch: ${memoryDir} is not a git repository. This tool requires a git-backed memory filesystem.`);
|
|
58519
58631
|
}
|
|
58520
58632
|
}
|
|
@@ -58528,7 +58640,7 @@ function normalizeMemoryLabel2(memoryDir, inputPath, fieldName) {
|
|
|
58528
58640
|
}
|
|
58529
58641
|
const isWindowsAbsolute = /^[a-zA-Z]:[\\/]/.test(raw);
|
|
58530
58642
|
if (isAbsolute10(raw) || isWindowsAbsolute) {
|
|
58531
|
-
const absolutePath =
|
|
58643
|
+
const absolutePath = resolve14(raw);
|
|
58532
58644
|
const relToMemory = relative6(memoryDir, absolutePath);
|
|
58533
58645
|
if (relToMemory && !relToMemory.startsWith("..") && !isAbsolute10(relToMemory)) {
|
|
58534
58646
|
return normalizeRelativeMemoryLabel2(relToMemory, fieldName);
|
|
@@ -58570,7 +58682,7 @@ function memoryPrefixError2(memoryDir) {
|
|
|
58570
58682
|
return `The memory_apply_patch tool can only be used to modify files in {${memoryDir}} or provided as a relative path`;
|
|
58571
58683
|
}
|
|
58572
58684
|
function resolveMemoryPath2(memoryDir, path11) {
|
|
58573
|
-
const absolute =
|
|
58685
|
+
const absolute = resolve14(memoryDir, path11);
|
|
58574
58686
|
const rel = relative6(memoryDir, absolute);
|
|
58575
58687
|
if (rel.startsWith("..") || isAbsolute10(rel)) {
|
|
58576
58688
|
throw new Error("memory_apply_patch: resolved path escapes memory directory");
|
|
@@ -58702,6 +58814,7 @@ async function commitAndPush2(memoryDir, pathspecs, reason) {
|
|
|
58702
58814
|
]);
|
|
58703
58815
|
const head = await runGit5(memoryDir, ["rev-parse", "HEAD"]);
|
|
58704
58816
|
const sha = head.stdout.trim();
|
|
58817
|
+
await maybeUpdateMemoryRemoteOrigin(memoryDir, agentId);
|
|
58705
58818
|
try {
|
|
58706
58819
|
await runGit5(memoryDir, ["push"]);
|
|
58707
58820
|
} catch (error) {
|
|
@@ -58776,7 +58889,10 @@ function buildOldNewChunks2(lines) {
|
|
|
58776
58889
|
var execFile11;
|
|
58777
58890
|
var init_MemoryApplyPatch2 = __esm(async () => {
|
|
58778
58891
|
init_context();
|
|
58779
|
-
await
|
|
58892
|
+
await __promiseAll([
|
|
58893
|
+
init_client2(),
|
|
58894
|
+
init_memoryGit()
|
|
58895
|
+
]);
|
|
58780
58896
|
execFile11 = promisify11(execFileCb4);
|
|
58781
58897
|
});
|
|
58782
58898
|
|
|
@@ -59342,7 +59458,7 @@ var init_client3 = __esm(() => {
|
|
|
59342
59458
|
this.emit("notification", notification);
|
|
59343
59459
|
}
|
|
59344
59460
|
sendRequest(method, params) {
|
|
59345
|
-
return new Promise((
|
|
59461
|
+
return new Promise((resolve17, reject) => {
|
|
59346
59462
|
const id = ++this.requestId;
|
|
59347
59463
|
const request = {
|
|
59348
59464
|
jsonrpc: "2.0",
|
|
@@ -59351,7 +59467,7 @@ var init_client3 = __esm(() => {
|
|
|
59351
59467
|
params
|
|
59352
59468
|
};
|
|
59353
59469
|
this.pendingRequests.set(id, {
|
|
59354
|
-
resolve:
|
|
59470
|
+
resolve: resolve17,
|
|
59355
59471
|
reject
|
|
59356
59472
|
});
|
|
59357
59473
|
this.sendMessage(request);
|
|
@@ -59471,14 +59587,14 @@ var init_python = __esm(() => {
|
|
|
59471
59587
|
}
|
|
59472
59588
|
console.log("[LSP] Installing pyright...");
|
|
59473
59589
|
const { spawn: spawn4 } = await import("node:child_process");
|
|
59474
|
-
return new Promise((
|
|
59590
|
+
return new Promise((resolve17, reject) => {
|
|
59475
59591
|
const proc = spawn4("npm", ["install", "-g", "pyright"], {
|
|
59476
59592
|
stdio: "inherit"
|
|
59477
59593
|
});
|
|
59478
59594
|
proc.on("exit", (code) => {
|
|
59479
59595
|
if (code === 0) {
|
|
59480
59596
|
console.log("[LSP] Successfully installed pyright");
|
|
59481
|
-
|
|
59597
|
+
resolve17();
|
|
59482
59598
|
} else {
|
|
59483
59599
|
reject(new Error(`npm install failed with code ${code}`));
|
|
59484
59600
|
}
|
|
@@ -59520,14 +59636,14 @@ var init_typescript = __esm(() => {
|
|
|
59520
59636
|
}
|
|
59521
59637
|
console.log("[LSP] Installing typescript-language-server and typescript...");
|
|
59522
59638
|
const { spawn: spawn4 } = await import("node:child_process");
|
|
59523
|
-
return new Promise((
|
|
59639
|
+
return new Promise((resolve17, reject) => {
|
|
59524
59640
|
const proc = spawn4("npm", ["install", "-g", "typescript-language-server", "typescript"], {
|
|
59525
59641
|
stdio: "inherit"
|
|
59526
59642
|
});
|
|
59527
59643
|
proc.on("exit", (code) => {
|
|
59528
59644
|
if (code === 0) {
|
|
59529
59645
|
console.log("[LSP] Successfully installed typescript-language-server");
|
|
59530
|
-
|
|
59646
|
+
resolve17();
|
|
59531
59647
|
} else {
|
|
59532
59648
|
reject(new Error(`npm install failed with code ${code}`));
|
|
59533
59649
|
}
|
|
@@ -59758,7 +59874,7 @@ async function read_lsp(args) {
|
|
|
59758
59874
|
const userCwd = process.env.USER_CWD || process.cwd();
|
|
59759
59875
|
const resolvedPath = path14.default.isAbsolute(args.file_path) ? args.file_path : path14.default.resolve(userCwd, args.file_path);
|
|
59760
59876
|
await lspManager2.touchFile(resolvedPath, false);
|
|
59761
|
-
await new Promise((
|
|
59877
|
+
await new Promise((resolve18) => setTimeout(resolve18, 100));
|
|
59762
59878
|
const diagnostics = lspManager2.getDiagnostics(resolvedPath);
|
|
59763
59879
|
if (diagnostics.length > 0) {
|
|
59764
59880
|
const errors = diagnostics.filter((d) => d.severity === 1);
|
|
@@ -62866,10 +62982,10 @@ var init_esm4 = __esm(() => {
|
|
|
62866
62982
|
return this[ENCODING] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
|
|
62867
62983
|
}
|
|
62868
62984
|
async promise() {
|
|
62869
|
-
return new Promise((
|
|
62985
|
+
return new Promise((resolve18, reject) => {
|
|
62870
62986
|
this.on(DESTROYED, () => reject(new Error("stream destroyed")));
|
|
62871
62987
|
this.on("error", (er) => reject(er));
|
|
62872
|
-
this.on("end", () =>
|
|
62988
|
+
this.on("end", () => resolve18());
|
|
62873
62989
|
});
|
|
62874
62990
|
}
|
|
62875
62991
|
[Symbol.asyncIterator]() {
|
|
@@ -62888,7 +63004,7 @@ var init_esm4 = __esm(() => {
|
|
|
62888
63004
|
return Promise.resolve({ done: false, value: res });
|
|
62889
63005
|
if (this[EOF])
|
|
62890
63006
|
return stop();
|
|
62891
|
-
let
|
|
63007
|
+
let resolve18;
|
|
62892
63008
|
let reject;
|
|
62893
63009
|
const onerr = (er) => {
|
|
62894
63010
|
this.off("data", ondata);
|
|
@@ -62902,19 +63018,19 @@ var init_esm4 = __esm(() => {
|
|
|
62902
63018
|
this.off("end", onend);
|
|
62903
63019
|
this.off(DESTROYED, ondestroy);
|
|
62904
63020
|
this.pause();
|
|
62905
|
-
|
|
63021
|
+
resolve18({ value, done: !!this[EOF] });
|
|
62906
63022
|
};
|
|
62907
63023
|
const onend = () => {
|
|
62908
63024
|
this.off("error", onerr);
|
|
62909
63025
|
this.off("data", ondata);
|
|
62910
63026
|
this.off(DESTROYED, ondestroy);
|
|
62911
63027
|
stop();
|
|
62912
|
-
|
|
63028
|
+
resolve18({ done: true, value: undefined });
|
|
62913
63029
|
};
|
|
62914
63030
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
62915
63031
|
return new Promise((res2, rej) => {
|
|
62916
63032
|
reject = rej;
|
|
62917
|
-
|
|
63033
|
+
resolve18 = res2;
|
|
62918
63034
|
this.once(DESTROYED, ondestroy);
|
|
62919
63035
|
this.once("error", onerr);
|
|
62920
63036
|
this.once("end", onend);
|
|
@@ -63600,8 +63716,8 @@ var init_esm5 = __esm(() => {
|
|
|
63600
63716
|
if (this.#asyncReaddirInFlight) {
|
|
63601
63717
|
await this.#asyncReaddirInFlight;
|
|
63602
63718
|
} else {
|
|
63603
|
-
let
|
|
63604
|
-
this.#asyncReaddirInFlight = new Promise((res) =>
|
|
63719
|
+
let resolve18 = () => {};
|
|
63720
|
+
this.#asyncReaddirInFlight = new Promise((res) => resolve18 = res);
|
|
63605
63721
|
try {
|
|
63606
63722
|
for (const e of await this.#fs.promises.readdir(fullpath, {
|
|
63607
63723
|
withFileTypes: true
|
|
@@ -63614,7 +63730,7 @@ var init_esm5 = __esm(() => {
|
|
|
63614
63730
|
children.provisional = 0;
|
|
63615
63731
|
}
|
|
63616
63732
|
this.#asyncReaddirInFlight = undefined;
|
|
63617
|
-
|
|
63733
|
+
resolve18();
|
|
63618
63734
|
}
|
|
63619
63735
|
return children.slice(0, children.provisional);
|
|
63620
63736
|
}
|
|
@@ -66636,10 +66752,10 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
|
|
|
66636
66752
|
crlfDelay: Number.POSITIVE_INFINITY
|
|
66637
66753
|
});
|
|
66638
66754
|
let rlClosed = false;
|
|
66639
|
-
const rlClosedPromise = new Promise((
|
|
66755
|
+
const rlClosedPromise = new Promise((resolve19) => {
|
|
66640
66756
|
rl.once("close", () => {
|
|
66641
66757
|
rlClosed = true;
|
|
66642
|
-
|
|
66758
|
+
resolve19();
|
|
66643
66759
|
});
|
|
66644
66760
|
});
|
|
66645
66761
|
rl.on("line", (line) => {
|
|
@@ -66650,9 +66766,9 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
|
|
|
66650
66766
|
proc2.stderr.on("data", (data) => {
|
|
66651
66767
|
stderrChunks.push(data);
|
|
66652
66768
|
});
|
|
66653
|
-
const exitCode = await new Promise((
|
|
66654
|
-
proc2.on("close",
|
|
66655
|
-
proc2.on("error", () =>
|
|
66769
|
+
const exitCode = await new Promise((resolve19) => {
|
|
66770
|
+
proc2.on("close", resolve19);
|
|
66771
|
+
proc2.on("error", () => resolve19(null));
|
|
66656
66772
|
});
|
|
66657
66773
|
if (!rlClosed) {
|
|
66658
66774
|
rl.close();
|
|
@@ -66892,6 +67008,14 @@ __export(exports_Task, {
|
|
|
66892
67008
|
task: () => task,
|
|
66893
67009
|
spawnBackgroundSubagentTask: () => spawnBackgroundSubagentTask
|
|
66894
67010
|
});
|
|
67011
|
+
async function resolveCompletionSummary(defaultSummary, completionSummary, result) {
|
|
67012
|
+
if (!completionSummary) {
|
|
67013
|
+
return defaultSummary;
|
|
67014
|
+
}
|
|
67015
|
+
const resolved = typeof completionSummary === "function" ? await completionSummary(result) : completionSummary;
|
|
67016
|
+
const trimmed = resolved.trim();
|
|
67017
|
+
return trimmed.length > 0 ? trimmed : defaultSummary;
|
|
67018
|
+
}
|
|
66895
67019
|
function buildTaskResultHeader(subagentType, subagentId, result, status) {
|
|
66896
67020
|
return [
|
|
66897
67021
|
`subagent_type=${subagentType}`,
|
|
@@ -66925,7 +67049,7 @@ ${result.report}
|
|
|
66925
67049
|
`);
|
|
66926
67050
|
}
|
|
66927
67051
|
function sleep3(ms) {
|
|
66928
|
-
return new Promise((
|
|
67052
|
+
return new Promise((resolve19) => setTimeout(resolve19, ms));
|
|
66929
67053
|
}
|
|
66930
67054
|
function resolveParentScope(parentScope) {
|
|
66931
67055
|
if (parentScope?.agentId) {
|
|
@@ -66979,9 +67103,12 @@ function spawnBackgroundSubagentTask(args) {
|
|
|
66979
67103
|
forkedContext,
|
|
66980
67104
|
parentScope,
|
|
66981
67105
|
silentCompletion,
|
|
67106
|
+
emitCompletionNotification,
|
|
67107
|
+
completionSummary,
|
|
66982
67108
|
onComplete,
|
|
66983
67109
|
deps
|
|
66984
67110
|
} = args;
|
|
67111
|
+
const shouldEmitCompletionNotification = emitCompletionNotification ?? !silentCompletion;
|
|
66985
67112
|
const resolvedParentScope = resolveParentScope(parentScope);
|
|
66986
67113
|
const spawnSubagentFn = deps?.spawnSubagentImpl ?? spawnSubagent;
|
|
66987
67114
|
const addToMessageQueueFn = deps?.addToMessageQueueImpl ?? addToMessageQueue;
|
|
@@ -67031,7 +67158,7 @@ function spawnBackgroundSubagentTask(args) {
|
|
|
67031
67158
|
appendToOutputFile(outputFile, `[onComplete error] ${errorMessage}
|
|
67032
67159
|
`);
|
|
67033
67160
|
}
|
|
67034
|
-
if (
|
|
67161
|
+
if (shouldEmitCompletionNotification) {
|
|
67035
67162
|
const subagentSnapshot = getSubagentSnapshotFn();
|
|
67036
67163
|
const subagentEntry = subagentSnapshot.agents.find((agent) => agent.id === subagentId);
|
|
67037
67164
|
const durationMs = Math.max(0, Date.now() - bgTask.startTime.getTime());
|
|
@@ -67042,10 +67169,12 @@ ${result.report || ""}` : `${header}
|
|
|
67042
67169
|
Error: ${result.error || "Subagent execution failed"}`;
|
|
67043
67170
|
const userCwd = process.env.USER_CWD || process.cwd();
|
|
67044
67171
|
const { content: truncatedResult } = truncateByChars(fullResult, LIMITS.TASK_OUTPUT_CHARS, "Task", { workingDirectory: userCwd, toolName: "Task" });
|
|
67172
|
+
const defaultSummary = `Agent "${description}" ${result.success ? "completed" : "failed"}`;
|
|
67173
|
+
const summary = await resolveCompletionSummary(defaultSummary, completionSummary, { success: result.success, error: result.error });
|
|
67045
67174
|
const notificationXml = formatTaskNotificationFn({
|
|
67046
67175
|
taskId,
|
|
67047
67176
|
status: result.success ? "completed" : "failed",
|
|
67048
|
-
summary
|
|
67177
|
+
summary,
|
|
67049
67178
|
result: truncatedResult,
|
|
67050
67179
|
outputFile,
|
|
67051
67180
|
usage: {
|
|
@@ -67077,7 +67206,7 @@ Error: ${result.error || "Subagent execution failed"}`;
|
|
|
67077
67206
|
appendToOutputFile(outputFile, `[onComplete error] ${callbackMessage}
|
|
67078
67207
|
`);
|
|
67079
67208
|
}
|
|
67080
|
-
if (
|
|
67209
|
+
if (shouldEmitCompletionNotification) {
|
|
67081
67210
|
const subagentSnapshot = getSubagentSnapshotFn();
|
|
67082
67211
|
const subagentEntry = subagentSnapshot.agents.find((agent) => agent.id === subagentId);
|
|
67083
67212
|
const durationMs = Math.max(0, Date.now() - bgTask.startTime.getTime());
|
|
@@ -67085,10 +67214,12 @@ Error: ${result.error || "Subagent execution failed"}`;
|
|
|
67085
67214
|
agentId: existingAgentId ?? "",
|
|
67086
67215
|
conversationId: existingConversationId
|
|
67087
67216
|
}, "error");
|
|
67217
|
+
const defaultSummary = `Agent "${description}" failed`;
|
|
67218
|
+
const summary = await resolveCompletionSummary(defaultSummary, completionSummary, { success: false, error: errorMessage });
|
|
67088
67219
|
const notificationXml = formatTaskNotificationFn({
|
|
67089
67220
|
taskId,
|
|
67090
67221
|
status: "failed",
|
|
67091
|
-
summary
|
|
67222
|
+
summary,
|
|
67092
67223
|
result: `${header}
|
|
67093
67224
|
|
|
67094
67225
|
Error: ${errorMessage}`,
|
|
@@ -70215,7 +70346,7 @@ var init_esm7 = __esm(() => {
|
|
|
70215
70346
|
});
|
|
70216
70347
|
|
|
70217
70348
|
// src/permissions/matcher.ts
|
|
70218
|
-
import { resolve as
|
|
70349
|
+
import { resolve as resolve21 } from "node:path";
|
|
70219
70350
|
function toolForMatch(toolName, options) {
|
|
70220
70351
|
return options?.canonicalizeToolNames === false ? toolName : canonicalToolName(toolName);
|
|
70221
70352
|
}
|
|
@@ -70270,7 +70401,7 @@ function resolveFilePathForMatching(filePath, workingDirectory, windowsContext)
|
|
|
70270
70401
|
if (windowsContext && isWindowsAbsolutePath(filePath)) {
|
|
70271
70402
|
return canonicalizeWindowsAbsolutePath(filePath);
|
|
70272
70403
|
}
|
|
70273
|
-
const resolved = normalizePath(
|
|
70404
|
+
const resolved = normalizePath(resolve21(workingDirectory, filePath));
|
|
70274
70405
|
return windowsContext ? canonicalizeWindowsAbsolutePath(resolved) : resolved;
|
|
70275
70406
|
}
|
|
70276
70407
|
function matchesFilePattern(query, pattern, workingDirectory, options) {
|
|
@@ -70396,7 +70527,7 @@ __export(exports_checker, {
|
|
|
70396
70527
|
checkPermissionWithHooks: () => checkPermissionWithHooks,
|
|
70397
70528
|
checkPermission: () => checkPermission
|
|
70398
70529
|
});
|
|
70399
|
-
import { relative as relative7, resolve as
|
|
70530
|
+
import { relative as relative7, resolve as resolve22 } from "node:path";
|
|
70400
70531
|
function envFlagEnabled(name) {
|
|
70401
70532
|
const value = process.env[name];
|
|
70402
70533
|
if (!value)
|
|
@@ -70686,13 +70817,13 @@ function extractFilePath(toolArgs) {
|
|
|
70686
70817
|
return null;
|
|
70687
70818
|
}
|
|
70688
70819
|
function isWithinAllowedDirectories(filePath, permissions, workingDirectory) {
|
|
70689
|
-
const absolutePath =
|
|
70820
|
+
const absolutePath = resolve22(workingDirectory, filePath);
|
|
70690
70821
|
if (absolutePath.startsWith(workingDirectory)) {
|
|
70691
70822
|
return true;
|
|
70692
70823
|
}
|
|
70693
70824
|
if (permissions.additionalDirectories) {
|
|
70694
70825
|
for (const dir of permissions.additionalDirectories) {
|
|
70695
|
-
const resolvedDir =
|
|
70826
|
+
const resolvedDir = resolve22(workingDirectory, dir);
|
|
70696
70827
|
if (absolutePath.startsWith(resolvedDir)) {
|
|
70697
70828
|
return true;
|
|
70698
70829
|
}
|
|
@@ -70704,7 +70835,7 @@ function getAllowedShellPathRoots(permissions, workingDirectory) {
|
|
|
70704
70835
|
const roots = [workingDirectory];
|
|
70705
70836
|
if (permissions.additionalDirectories) {
|
|
70706
70837
|
for (const dir of permissions.additionalDirectories) {
|
|
70707
|
-
roots.push(
|
|
70838
|
+
roots.push(resolve22(workingDirectory, dir));
|
|
70708
70839
|
}
|
|
70709
70840
|
}
|
|
70710
70841
|
return roots;
|
|
@@ -70806,7 +70937,9 @@ function getDefaultDecision(toolName, toolArgs) {
|
|
|
70806
70937
|
"GlobGemini",
|
|
70807
70938
|
"SearchFileContent",
|
|
70808
70939
|
"WriteTodos",
|
|
70809
|
-
"ReadManyFiles"
|
|
70940
|
+
"ReadManyFiles",
|
|
70941
|
+
"memory",
|
|
70942
|
+
"memory_apply_patch"
|
|
70810
70943
|
];
|
|
70811
70944
|
if (autoAllowTools.includes(toolName)) {
|
|
70812
70945
|
return "allow";
|
|
@@ -71055,7 +71188,7 @@ __export(exports_analyzer, {
|
|
|
71055
71188
|
analyzeApprovalContext: () => analyzeApprovalContext
|
|
71056
71189
|
});
|
|
71057
71190
|
import { homedir as homedir18 } from "node:os";
|
|
71058
|
-
import { dirname as dirname12, relative as relative8, resolve as
|
|
71191
|
+
import { dirname as dirname12, relative as relative8, resolve as resolve23, win32 as win322 } from "node:path";
|
|
71059
71192
|
function normalizeOsPath(path20) {
|
|
71060
71193
|
return path20.replace(/\\/g, "/");
|
|
71061
71194
|
}
|
|
@@ -71064,7 +71197,7 @@ function isWindowsPath(path20) {
|
|
|
71064
71197
|
}
|
|
71065
71198
|
function resolvePathForContext(basePath, targetPath) {
|
|
71066
71199
|
const windows = isWindowsPath(basePath) || isWindowsPath(targetPath);
|
|
71067
|
-
return windows ? win322.resolve(basePath, targetPath) :
|
|
71200
|
+
return windows ? win322.resolve(basePath, targetPath) : resolve23(basePath, targetPath);
|
|
71068
71201
|
}
|
|
71069
71202
|
function relativePathForContext(basePath, targetPath) {
|
|
71070
71203
|
const windows = isWindowsPath(basePath) || isWindowsPath(targetPath);
|
|
@@ -71253,7 +71386,7 @@ function containsDangerousCommand(command) {
|
|
|
71253
71386
|
}
|
|
71254
71387
|
return false;
|
|
71255
71388
|
}
|
|
71256
|
-
function
|
|
71389
|
+
function escapeRegex2(text) {
|
|
71257
71390
|
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
71258
71391
|
}
|
|
71259
71392
|
function normalizePathSeparators(path20) {
|
|
@@ -71298,17 +71431,17 @@ function detectSkillScript(command, workingDir) {
|
|
|
71298
71431
|
}
|
|
71299
71432
|
return null;
|
|
71300
71433
|
};
|
|
71301
|
-
const projectRegex = new RegExp(`^${
|
|
71434
|
+
const projectRegex = new RegExp(`^${escapeRegex2(normalizedWorkingDir)}/\\.skills/(.+?)/scripts/`);
|
|
71302
71435
|
const projectSkill = detect("project", projectRegex);
|
|
71303
71436
|
if (projectSkill) {
|
|
71304
71437
|
return projectSkill;
|
|
71305
71438
|
}
|
|
71306
|
-
const agentRegex = new RegExp(`^${
|
|
71439
|
+
const agentRegex = new RegExp(`^${escapeRegex2(normalizedHomeDir)}/\\.letta/agents/[^/]+/skills/(.+?)/scripts/`);
|
|
71307
71440
|
const agentSkill = detect("agent-scoped", agentRegex);
|
|
71308
71441
|
if (agentSkill) {
|
|
71309
71442
|
return agentSkill;
|
|
71310
71443
|
}
|
|
71311
|
-
const globalRegex = new RegExp(`^${
|
|
71444
|
+
const globalRegex = new RegExp(`^${escapeRegex2(normalizedHomeDir)}/\\.letta/skills/(.+?)/scripts/`);
|
|
71312
71445
|
const globalSkill = detect("global", globalRegex);
|
|
71313
71446
|
if (globalSkill) {
|
|
71314
71447
|
return globalSkill;
|
|
@@ -71737,8 +71870,8 @@ function acquireSwitchLock() {
|
|
|
71737
71870
|
const lock = getSwitchLock();
|
|
71738
71871
|
lock.refCount++;
|
|
71739
71872
|
if (lock.refCount === 1) {
|
|
71740
|
-
lock.promise = new Promise((
|
|
71741
|
-
lock.resolve =
|
|
71873
|
+
lock.promise = new Promise((resolve24) => {
|
|
71874
|
+
lock.resolve = resolve24;
|
|
71742
71875
|
});
|
|
71743
71876
|
}
|
|
71744
71877
|
}
|
|
@@ -73037,13 +73170,6 @@ var init_memoryFilesystem = __esm(() => {
|
|
|
73037
73170
|
});
|
|
73038
73171
|
|
|
73039
73172
|
// 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
73173
|
function gatherInitGitContext() {
|
|
73048
73174
|
try {
|
|
73049
73175
|
const git = gatherGitContextSnapshot({
|
|
@@ -73072,154 +73198,6 @@ ${git.recentCommits || "No commits yet"}
|
|
|
73072
73198
|
};
|
|
73073
73199
|
}
|
|
73074
73200
|
}
|
|
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
73201
|
function buildInitMessage(args) {
|
|
73224
73202
|
const memfsSection = args.memoryDir ? `
|
|
73225
73203
|
## Memory filesystem
|
|
@@ -73265,12 +73243,10 @@ Once invoked, follow the instructions from the \`context_doctor\` skill.
|
|
|
73265
73243
|
${args.gitContext}
|
|
73266
73244
|
${SYSTEM_REMINDER_CLOSE}`;
|
|
73267
73245
|
}
|
|
73268
|
-
var init_initCommand = __esm(
|
|
73269
|
-
init_memoryFilesystem();
|
|
73246
|
+
var init_initCommand = __esm(() => {
|
|
73270
73247
|
init_constants();
|
|
73271
73248
|
init_gitContext();
|
|
73272
73249
|
init_subagentState();
|
|
73273
|
-
await init_settings_manager();
|
|
73274
73250
|
});
|
|
73275
73251
|
|
|
73276
73252
|
// src/cli/helpers/errorFormatter.ts
|
|
@@ -74516,7 +74492,7 @@ var init_approval_result_normalization = __esm(() => {
|
|
|
74516
74492
|
});
|
|
74517
74493
|
|
|
74518
74494
|
// src/agent/clientSkills.ts
|
|
74519
|
-
import { join as
|
|
74495
|
+
import { join as join23 } from "node:path";
|
|
74520
74496
|
function toClientSkill(skill2) {
|
|
74521
74497
|
return {
|
|
74522
74498
|
name: skill2.id,
|
|
@@ -74525,12 +74501,12 @@ function toClientSkill(skill2) {
|
|
|
74525
74501
|
};
|
|
74526
74502
|
}
|
|
74527
74503
|
function resolveSkillDiscoveryContext(options) {
|
|
74528
|
-
const legacySkillsDirectory = options.skillsDirectory ?? getSkillsDirectory() ??
|
|
74504
|
+
const legacySkillsDirectory = options.skillsDirectory ?? getSkillsDirectory() ?? join23(process.cwd(), SKILLS_DIR);
|
|
74529
74505
|
const skillSources = options.skillSources ?? getSkillSources();
|
|
74530
74506
|
return { legacySkillsDirectory, skillSources };
|
|
74531
74507
|
}
|
|
74532
74508
|
function getPrimaryProjectSkillsDirectory() {
|
|
74533
|
-
return
|
|
74509
|
+
return join23(process.cwd(), ".agents", "skills");
|
|
74534
74510
|
}
|
|
74535
74511
|
async function buildClientSkillsPayload(options = {}) {
|
|
74536
74512
|
const { legacySkillsDirectory, skillSources } = resolveSkillDiscoveryContext(options);
|
|
@@ -75979,7 +75955,7 @@ import {
|
|
|
75979
75955
|
writeFile as writeFile4
|
|
75980
75956
|
} from "node:fs/promises";
|
|
75981
75957
|
import { homedir as homedir20, tmpdir as tmpdir3 } from "node:os";
|
|
75982
|
-
import { join as
|
|
75958
|
+
import { join as join24 } from "node:path";
|
|
75983
75959
|
function buildReflectionSubagentPrompt(input) {
|
|
75984
75960
|
const lines = [];
|
|
75985
75961
|
if (input.cwd) {
|
|
@@ -76012,7 +75988,7 @@ async function collectParentMemoryFiles(memoryDir) {
|
|
|
76012
75988
|
return a.name.localeCompare(b.name);
|
|
76013
75989
|
});
|
|
76014
75990
|
for (const entry of sortedEntries) {
|
|
76015
|
-
const entryPath =
|
|
75991
|
+
const entryPath = join24(currentDir, entry.name);
|
|
76016
75992
|
const relativePath = relativeDir ? `${relativeDir}/${entry.name}` : entry.name;
|
|
76017
75993
|
if (entry.isDirectory()) {
|
|
76018
75994
|
await walk(entryPath, relativePath);
|
|
@@ -76172,7 +76148,7 @@ function getTranscriptRoot() {
|
|
|
76172
76148
|
if (envRoot) {
|
|
76173
76149
|
return envRoot;
|
|
76174
76150
|
}
|
|
76175
|
-
return
|
|
76151
|
+
return join24(homedir20(), ".letta", DEFAULT_TRANSCRIPT_DIR);
|
|
76176
76152
|
}
|
|
76177
76153
|
function defaultState() {
|
|
76178
76154
|
return { auto_cursor_line: 0 };
|
|
@@ -76284,14 +76260,14 @@ async function readTranscriptLines(paths) {
|
|
|
76284
76260
|
}
|
|
76285
76261
|
function buildPayloadPath(kind) {
|
|
76286
76262
|
const nonce = Math.random().toString(36).slice(2, 8);
|
|
76287
|
-
return
|
|
76263
|
+
return join24(tmpdir3(), `letta-${kind}-${nonce}.txt`);
|
|
76288
76264
|
}
|
|
76289
76265
|
function getReflectionTranscriptPaths(agentId, conversationId) {
|
|
76290
|
-
const rootDir =
|
|
76266
|
+
const rootDir = join24(getTranscriptRoot(), sanitizePathSegment(agentId), sanitizePathSegment(conversationId));
|
|
76291
76267
|
return {
|
|
76292
76268
|
rootDir,
|
|
76293
|
-
transcriptPath:
|
|
76294
|
-
statePath:
|
|
76269
|
+
transcriptPath: join24(rootDir, "transcript.jsonl"),
|
|
76270
|
+
statePath: join24(rootDir, "state.json")
|
|
76295
76271
|
};
|
|
76296
76272
|
}
|
|
76297
76273
|
async function appendTranscriptDeltaJsonl(agentId, conversationId, lines) {
|
|
@@ -76355,14 +76331,14 @@ var init_reflectionTranscript = __esm(async () => {
|
|
|
76355
76331
|
|
|
76356
76332
|
// src/cli/helpers/chunkLog.ts
|
|
76357
76333
|
import {
|
|
76358
|
-
existsSync as
|
|
76334
|
+
existsSync as existsSync19,
|
|
76359
76335
|
mkdirSync as mkdirSync14,
|
|
76360
|
-
readdirSync as
|
|
76336
|
+
readdirSync as readdirSync8,
|
|
76361
76337
|
unlinkSync as unlinkSync7,
|
|
76362
76338
|
writeFileSync as writeFileSync11
|
|
76363
76339
|
} from "node:fs";
|
|
76364
76340
|
import { homedir as homedir21 } from "node:os";
|
|
76365
|
-
import { join as
|
|
76341
|
+
import { join as join25 } from "node:path";
|
|
76366
76342
|
function truncateStr(value, maxLen) {
|
|
76367
76343
|
if (value === null || value === undefined)
|
|
76368
76344
|
return "";
|
|
@@ -76426,8 +76402,8 @@ class ChunkLog {
|
|
|
76426
76402
|
agentDir = null;
|
|
76427
76403
|
dirCreated = false;
|
|
76428
76404
|
init(agentId, sessionId) {
|
|
76429
|
-
this.agentDir =
|
|
76430
|
-
this.logPath =
|
|
76405
|
+
this.agentDir = join25(LOG_BASE_DIR, agentId);
|
|
76406
|
+
this.logPath = join25(this.agentDir, `${sessionId}.jsonl`);
|
|
76431
76407
|
this.buffer = [];
|
|
76432
76408
|
this.dirty = false;
|
|
76433
76409
|
this.dirCreated = false;
|
|
@@ -76456,7 +76432,7 @@ class ChunkLog {
|
|
|
76456
76432
|
if (this.dirCreated || !this.agentDir)
|
|
76457
76433
|
return;
|
|
76458
76434
|
try {
|
|
76459
|
-
if (!
|
|
76435
|
+
if (!existsSync19(this.agentDir)) {
|
|
76460
76436
|
mkdirSync14(this.agentDir, { recursive: true });
|
|
76461
76437
|
}
|
|
76462
76438
|
this.dirCreated = true;
|
|
@@ -76481,14 +76457,14 @@ class ChunkLog {
|
|
|
76481
76457
|
if (!this.agentDir)
|
|
76482
76458
|
return;
|
|
76483
76459
|
try {
|
|
76484
|
-
if (!
|
|
76460
|
+
if (!existsSync19(this.agentDir))
|
|
76485
76461
|
return;
|
|
76486
|
-
const files =
|
|
76462
|
+
const files = readdirSync8(this.agentDir).filter((f) => f.endsWith(".jsonl")).sort();
|
|
76487
76463
|
if (files.length >= MAX_SESSION_FILES2) {
|
|
76488
76464
|
const toDelete = files.slice(0, files.length - MAX_SESSION_FILES2 + 1);
|
|
76489
76465
|
for (const file of toDelete) {
|
|
76490
76466
|
try {
|
|
76491
|
-
unlinkSync7(
|
|
76467
|
+
unlinkSync7(join25(this.agentDir, file));
|
|
76492
76468
|
} catch (e) {
|
|
76493
76469
|
debugWarn("chunkLog", `Failed to delete old session log ${file}: ${e instanceof Error ? e.message : String(e)}`);
|
|
76494
76470
|
}
|
|
@@ -76502,7 +76478,7 @@ class ChunkLog {
|
|
|
76502
76478
|
var MAX_ENTRIES = 100, CONTENT_TRUNCATE_LEN = 200, MAX_SESSION_FILES2 = 5, LOG_BASE_DIR, chunkLog;
|
|
76503
76479
|
var init_chunkLog = __esm(() => {
|
|
76504
76480
|
init_debug();
|
|
76505
|
-
LOG_BASE_DIR =
|
|
76481
|
+
LOG_BASE_DIR = join25(homedir21(), ".letta", "logs", "chunk-logs");
|
|
76506
76482
|
chunkLog = new ChunkLog;
|
|
76507
76483
|
});
|
|
76508
76484
|
|
|
@@ -76610,11 +76586,11 @@ async function discoverFallbackRunIdWithTimeout(client, ctx) {
|
|
|
76610
76586
|
return withTimeout(discoverFallbackRunIdForResume(client, ctx), FALLBACK_RUN_DISCOVERY_TIMEOUT_MS, `Fallback run discovery timed out after ${FALLBACK_RUN_DISCOVERY_TIMEOUT_MS}ms`);
|
|
76611
76587
|
}
|
|
76612
76588
|
function withTimeout(promise, timeoutMs, timeoutMessage) {
|
|
76613
|
-
return new Promise((
|
|
76589
|
+
return new Promise((resolve24, reject) => {
|
|
76614
76590
|
const timer = setTimeout(() => reject(new Error(timeoutMessage)), timeoutMs);
|
|
76615
76591
|
promise.then((value) => {
|
|
76616
76592
|
clearTimeout(timer);
|
|
76617
|
-
|
|
76593
|
+
resolve24(value);
|
|
76618
76594
|
}, (error) => {
|
|
76619
76595
|
clearTimeout(timer);
|
|
76620
76596
|
reject(error);
|
|
@@ -77249,11 +77225,6 @@ var init_catalog = __esm(() => {
|
|
|
77249
77225
|
id: "toolset-change",
|
|
77250
77226
|
description: "Client-side toolset change context",
|
|
77251
77227
|
modes: ["interactive"]
|
|
77252
|
-
},
|
|
77253
|
-
{
|
|
77254
|
-
id: "auto-init",
|
|
77255
|
-
description: "Auto-init background onboarding notification",
|
|
77256
|
-
modes: ["interactive"]
|
|
77257
77228
|
}
|
|
77258
77229
|
];
|
|
77259
77230
|
SHARED_REMINDER_IDS = SHARED_REMINDER_CATALOG.map((entry) => entry.id);
|
|
@@ -77385,13 +77356,6 @@ async function buildReflectionCompactionReminder(context3) {
|
|
|
77385
77356
|
}
|
|
77386
77357
|
return buildCompactionMemoryReminder(context3.agent.id);
|
|
77387
77358
|
}
|
|
77388
|
-
async function buildAutoInitReminder(context3) {
|
|
77389
|
-
if (!context3.state.pendingAutoInitReminder)
|
|
77390
|
-
return null;
|
|
77391
|
-
context3.state.pendingAutoInitReminder = false;
|
|
77392
|
-
const { AUTO_INIT_REMINDER: AUTO_INIT_REMINDER2 } = await Promise.resolve().then(() => (init_promptAssets(), exports_promptAssets));
|
|
77393
|
-
return AUTO_INIT_REMINDER2;
|
|
77394
|
-
}
|
|
77395
77359
|
function escapeXml2(value) {
|
|
77396
77360
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
77397
77361
|
}
|
|
@@ -77541,8 +77505,7 @@ var init_engine = __esm(async () => {
|
|
|
77541
77505
|
"reflection-step-count": buildReflectionStepReminder,
|
|
77542
77506
|
"reflection-compaction": buildReflectionCompactionReminder,
|
|
77543
77507
|
"command-io": buildCommandIoReminder,
|
|
77544
|
-
"toolset-change": buildToolsetChangeReminder
|
|
77545
|
-
"auto-init": buildAutoInitReminder
|
|
77508
|
+
"toolset-change": buildToolsetChangeReminder
|
|
77546
77509
|
};
|
|
77547
77510
|
assertSharedReminderCoverage();
|
|
77548
77511
|
});
|
|
@@ -77640,7 +77603,7 @@ var init_constants2 = __esm(() => {
|
|
|
77640
77603
|
});
|
|
77641
77604
|
|
|
77642
77605
|
// src/websocket/listener/remote-settings.ts
|
|
77643
|
-
import { existsSync as
|
|
77606
|
+
import { existsSync as existsSync20, readFileSync as readFileSync11 } from "node:fs";
|
|
77644
77607
|
import { mkdir as mkdir5, writeFile as writeFile5 } from "node:fs/promises";
|
|
77645
77608
|
import { homedir as homedir22 } from "node:os";
|
|
77646
77609
|
import path20 from "node:path";
|
|
@@ -77654,8 +77617,8 @@ function loadRemoteSettings() {
|
|
|
77654
77617
|
let loaded = {};
|
|
77655
77618
|
try {
|
|
77656
77619
|
const settingsPath = getRemoteSettingsPath();
|
|
77657
|
-
if (
|
|
77658
|
-
const raw =
|
|
77620
|
+
if (existsSync20(settingsPath)) {
|
|
77621
|
+
const raw = readFileSync11(settingsPath, "utf-8");
|
|
77659
77622
|
const parsed = JSON.parse(raw);
|
|
77660
77623
|
loaded = parsed;
|
|
77661
77624
|
}
|
|
@@ -77663,7 +77626,7 @@ function loadRemoteSettings() {
|
|
|
77663
77626
|
if (loaded.cwdMap) {
|
|
77664
77627
|
const validCwdMap = {};
|
|
77665
77628
|
for (const [key, value] of Object.entries(loaded.cwdMap)) {
|
|
77666
|
-
if (typeof value === "string" &&
|
|
77629
|
+
if (typeof value === "string" && existsSync20(value)) {
|
|
77667
77630
|
validCwdMap[key] = value;
|
|
77668
77631
|
}
|
|
77669
77632
|
}
|
|
@@ -77690,13 +77653,13 @@ function saveRemoteSettings(updates) {
|
|
|
77690
77653
|
function loadLegacyCwdCache() {
|
|
77691
77654
|
try {
|
|
77692
77655
|
const legacyPath = path20.join(homedir22(), ".letta", "cwd-cache.json");
|
|
77693
|
-
if (!
|
|
77656
|
+
if (!existsSync20(legacyPath))
|
|
77694
77657
|
return {};
|
|
77695
|
-
const raw =
|
|
77658
|
+
const raw = readFileSync11(legacyPath, "utf-8");
|
|
77696
77659
|
const parsed = JSON.parse(raw);
|
|
77697
77660
|
const result = {};
|
|
77698
77661
|
for (const [key, value] of Object.entries(parsed)) {
|
|
77699
|
-
if (typeof value === "string" &&
|
|
77662
|
+
if (typeof value === "string" && existsSync20(value)) {
|
|
77700
77663
|
result[key] = value;
|
|
77701
77664
|
}
|
|
77702
77665
|
}
|
|
@@ -77894,7 +77857,7 @@ function requestApprovalOverWS(runtime, socket, requestId, controlRequest) {
|
|
|
77894
77857
|
if (isInterrupted()) {
|
|
77895
77858
|
return Promise.reject(new Error("Cancelled by user"));
|
|
77896
77859
|
}
|
|
77897
|
-
return new Promise((
|
|
77860
|
+
return new Promise((resolve24, reject) => {
|
|
77898
77861
|
let settled = false;
|
|
77899
77862
|
const cleanupAbortListener = () => {
|
|
77900
77863
|
abortSignal?.removeEventListener("abort", handleAbort);
|
|
@@ -77905,7 +77868,7 @@ function requestApprovalOverWS(runtime, socket, requestId, controlRequest) {
|
|
|
77905
77868
|
}
|
|
77906
77869
|
settled = true;
|
|
77907
77870
|
cleanupAbortListener();
|
|
77908
|
-
|
|
77871
|
+
resolve24(response);
|
|
77909
77872
|
};
|
|
77910
77873
|
const wrappedReject = (error) => {
|
|
77911
77874
|
if (settled) {
|
|
@@ -80886,7 +80849,7 @@ async function sendMessageStreamWithRetry(conversationId, messages, opts, socket
|
|
|
80886
80849
|
conversationId
|
|
80887
80850
|
});
|
|
80888
80851
|
}
|
|
80889
|
-
await new Promise((
|
|
80852
|
+
await new Promise((resolve24) => setTimeout(resolve24, delayMs));
|
|
80890
80853
|
if (abortSignal?.aborted) {
|
|
80891
80854
|
throw new Error("Cancelled by user");
|
|
80892
80855
|
}
|
|
@@ -80941,7 +80904,7 @@ async function sendMessageStreamWithRetry(conversationId, messages, opts, socket
|
|
|
80941
80904
|
agentId: runtime.agentId ?? undefined,
|
|
80942
80905
|
conversationId
|
|
80943
80906
|
});
|
|
80944
|
-
await new Promise((
|
|
80907
|
+
await new Promise((resolve24) => setTimeout(resolve24, delayMs));
|
|
80945
80908
|
if (abortSignal?.aborted) {
|
|
80946
80909
|
throw new Error("Cancelled by user");
|
|
80947
80910
|
}
|
|
@@ -81016,7 +80979,7 @@ async function sendApprovalContinuationWithRetry(conversationId, messages, opts,
|
|
|
81016
80979
|
retryAfterMs
|
|
81017
80980
|
});
|
|
81018
80981
|
transientRetries = attempt;
|
|
81019
|
-
await new Promise((
|
|
80982
|
+
await new Promise((resolve24) => setTimeout(resolve24, delayMs));
|
|
81020
80983
|
if (abortSignal?.aborted) {
|
|
81021
80984
|
throw new Error("Cancelled by user");
|
|
81022
80985
|
}
|
|
@@ -81061,7 +81024,7 @@ async function sendApprovalContinuationWithRetry(conversationId, messages, opts,
|
|
|
81061
81024
|
category: "conversation_busy",
|
|
81062
81025
|
attempt: conversationBusyRetries
|
|
81063
81026
|
});
|
|
81064
|
-
await new Promise((
|
|
81027
|
+
await new Promise((resolve24) => setTimeout(resolve24, retryDelayMs));
|
|
81065
81028
|
if (abortSignal?.aborted) {
|
|
81066
81029
|
throw new Error("Cancelled by user");
|
|
81067
81030
|
}
|
|
@@ -81524,15 +81487,18 @@ function buildMaybeLaunchReflectionSubagent(params) {
|
|
|
81524
81487
|
parentMemory
|
|
81525
81488
|
});
|
|
81526
81489
|
const { spawnBackgroundSubagentTask: spawnBackgroundSubagentTask2 } = await init_Task2().then(() => exports_Task);
|
|
81490
|
+
const reflectionSuccessSummary = "Reflected on the memory palace, the halls remember more now";
|
|
81527
81491
|
spawnBackgroundSubagentTask2({
|
|
81528
81492
|
subagentType: "reflection",
|
|
81529
81493
|
prompt: reflectionPrompt,
|
|
81530
81494
|
description: AUTO_REFLECTION_DESCRIPTION,
|
|
81531
81495
|
silentCompletion: true,
|
|
81496
|
+
emitCompletionNotification: true,
|
|
81497
|
+
completionSummary: ({ success, error }) => success ? reflectionSuccessSummary : `Tried to reflect, but got lost in the palace: ${error || "Unknown error"}`,
|
|
81532
81498
|
parentScope: { agentId, conversationId },
|
|
81533
81499
|
onComplete: async ({ success, error }) => {
|
|
81534
81500
|
await finalizeAutoReflectionPayload(agentId, conversationId, autoPayload.payloadPath, autoPayload.endSnapshotLine, success);
|
|
81535
|
-
|
|
81501
|
+
await handleMemorySubagentCompletion({
|
|
81536
81502
|
agentId,
|
|
81537
81503
|
conversationId,
|
|
81538
81504
|
subagentType: "reflection",
|
|
@@ -81543,12 +81509,6 @@ function buildMaybeLaunchReflectionSubagent(params) {
|
|
|
81543
81509
|
recompileQueuedByConversation: runtime.listener.queuedSystemPromptRecompileByConversation,
|
|
81544
81510
|
logRecompileFailure: (message) => debugWarn("memory", message)
|
|
81545
81511
|
});
|
|
81546
|
-
addToMessageQueue({
|
|
81547
|
-
kind: "task_notification",
|
|
81548
|
-
text: `<task-notification><summary>${msg}</summary></task-notification>`,
|
|
81549
|
-
agentId,
|
|
81550
|
-
conversationId
|
|
81551
|
-
});
|
|
81552
81512
|
}
|
|
81553
81513
|
});
|
|
81554
81514
|
debugLog("memory", `Auto-launched reflection subagent (${triggerSource})`);
|
|
@@ -81911,7 +81871,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
|
|
|
81911
81871
|
agentId,
|
|
81912
81872
|
conversationId
|
|
81913
81873
|
});
|
|
81914
|
-
await new Promise((
|
|
81874
|
+
await new Promise((resolve24) => setTimeout(resolve24, delayMs));
|
|
81915
81875
|
if (turnAbortSignal.aborted) {
|
|
81916
81876
|
throw new Error("Cancelled by user");
|
|
81917
81877
|
}
|
|
@@ -81956,7 +81916,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
|
|
|
81956
81916
|
agentId,
|
|
81957
81917
|
conversationId
|
|
81958
81918
|
});
|
|
81959
|
-
await new Promise((
|
|
81919
|
+
await new Promise((resolve24) => setTimeout(resolve24, delayMs));
|
|
81960
81920
|
if (turnAbortSignal.aborted) {
|
|
81961
81921
|
throw new Error("Cancelled by user");
|
|
81962
81922
|
}
|
|
@@ -82128,7 +82088,6 @@ var init_turn = __esm(async () => {
|
|
|
82128
82088
|
init_memoryFilesystem();
|
|
82129
82089
|
init_turn_recovery_policy();
|
|
82130
82090
|
init_errorFormatter();
|
|
82131
|
-
init_messageQueueBridge();
|
|
82132
82091
|
init_subagentState();
|
|
82133
82092
|
init_planModeReminder();
|
|
82134
82093
|
init_debug();
|
|
@@ -82327,11 +82286,11 @@ var init_commands = __esm(async () => {
|
|
|
82327
82286
|
init_memory();
|
|
82328
82287
|
init_memoryFilesystem();
|
|
82329
82288
|
init_promptAssets();
|
|
82289
|
+
init_initCommand();
|
|
82330
82290
|
init_constants();
|
|
82331
82291
|
init_runtime();
|
|
82332
82292
|
await __promiseAll([
|
|
82333
82293
|
init_client2(),
|
|
82334
|
-
init_initCommand(),
|
|
82335
82294
|
init_settings_manager(),
|
|
82336
82295
|
init_errorReporting(),
|
|
82337
82296
|
init_protocol_outbound(),
|
|
@@ -82347,6 +82306,25 @@ var init_commands = __esm(async () => {
|
|
|
82347
82306
|
|
|
82348
82307
|
// src/websocket/listener/protocol-outbound.ts
|
|
82349
82308
|
import WebSocket2 from "ws";
|
|
82309
|
+
function getCachedDeviceGitContext(cwd2) {
|
|
82310
|
+
const now = Date.now();
|
|
82311
|
+
const cached = gitContextCache.get(cwd2);
|
|
82312
|
+
if (cached && cached.expiresAt > now) {
|
|
82313
|
+
return cached.value;
|
|
82314
|
+
}
|
|
82315
|
+
const value = getGitContext(cwd2);
|
|
82316
|
+
gitContextCache.set(cwd2, {
|
|
82317
|
+
expiresAt: now + GIT_CONTEXT_CACHE_TTL_MS,
|
|
82318
|
+
value
|
|
82319
|
+
});
|
|
82320
|
+
if (gitContextCache.size > MAX_GIT_CONTEXT_CACHE_ENTRIES) {
|
|
82321
|
+
const oldestKey = gitContextCache.keys().next().value;
|
|
82322
|
+
if (oldestKey) {
|
|
82323
|
+
gitContextCache.delete(oldestKey);
|
|
82324
|
+
}
|
|
82325
|
+
}
|
|
82326
|
+
return value;
|
|
82327
|
+
}
|
|
82350
82328
|
function getListenerRuntime(runtime) {
|
|
82351
82329
|
if (!runtime)
|
|
82352
82330
|
return null;
|
|
@@ -82401,7 +82379,7 @@ function buildDeviceStatus(runtime, params) {
|
|
|
82401
82379
|
is_processing: false,
|
|
82402
82380
|
current_permission_mode: permissionMode.getMode(),
|
|
82403
82381
|
current_working_directory: fallbackCwd,
|
|
82404
|
-
git_context:
|
|
82382
|
+
git_context: getCachedDeviceGitContext(fallbackCwd),
|
|
82405
82383
|
letta_code_version: process.env.npm_package_version || null,
|
|
82406
82384
|
current_toolset: null,
|
|
82407
82385
|
current_toolset_preference: "auto",
|
|
@@ -82448,7 +82426,7 @@ function buildDeviceStatus(runtime, params) {
|
|
|
82448
82426
|
is_processing: !!conversationRuntime?.isProcessing,
|
|
82449
82427
|
current_permission_mode: conversationPermissionModeState.mode,
|
|
82450
82428
|
current_working_directory: resolvedCwd,
|
|
82451
|
-
git_context:
|
|
82429
|
+
git_context: getCachedDeviceGitContext(resolvedCwd),
|
|
82452
82430
|
letta_code_version: process.env.npm_package_version || null,
|
|
82453
82431
|
current_toolset: conversationRuntime?.currentToolset ?? (toolsetPreference === "auto" ? null : toolsetPreference),
|
|
82454
82432
|
current_toolset_preference: conversationRuntime?.currentToolsetPreference ?? toolsetPreference,
|
|
@@ -82543,7 +82521,9 @@ function emitProtocolV2Message(socket, runtime, message, scope) {
|
|
|
82543
82521
|
});
|
|
82544
82522
|
return;
|
|
82545
82523
|
}
|
|
82546
|
-
|
|
82524
|
+
if (isDebugEnabled()) {
|
|
82525
|
+
console.log(`[Listen V2] Emitting ${message.type} (seq=${eventSeq})`);
|
|
82526
|
+
}
|
|
82547
82527
|
safeEmitWsEvent("send", "protocol", outbound);
|
|
82548
82528
|
}
|
|
82549
82529
|
function emitDeviceStatusUpdate(socket, runtime, scope) {
|
|
@@ -82764,12 +82744,14 @@ function emitStreamDelta(socket, runtime, delta, scope, subagentId) {
|
|
|
82764
82744
|
};
|
|
82765
82745
|
emitProtocolV2Message(socket, runtime, message, scope);
|
|
82766
82746
|
}
|
|
82747
|
+
var GIT_CONTEXT_CACHE_TTL_MS = 15000, MAX_GIT_CONTEXT_CACHE_ENTRIES = 64, gitContextCache;
|
|
82767
82748
|
var init_protocol_outbound = __esm(async () => {
|
|
82768
82749
|
init_memoryFilesystem();
|
|
82769
82750
|
init_gitContext();
|
|
82770
82751
|
init_subagentState();
|
|
82771
82752
|
init_mode();
|
|
82772
82753
|
init_process_manager();
|
|
82754
|
+
init_debug();
|
|
82773
82755
|
init_constants2();
|
|
82774
82756
|
init_cwd();
|
|
82775
82757
|
init_permissionMode();
|
|
@@ -82779,6 +82761,7 @@ var init_protocol_outbound = __esm(async () => {
|
|
|
82779
82761
|
init_settings_manager(),
|
|
82780
82762
|
init_commands()
|
|
82781
82763
|
]);
|
|
82764
|
+
gitContextCache = new Map;
|
|
82782
82765
|
});
|
|
82783
82766
|
|
|
82784
82767
|
// src/websocket/listener/queue.ts
|
|
@@ -82965,6 +82948,9 @@ function consumeQueuedTurn(runtime) {
|
|
|
82965
82948
|
if (!isCoalescable(item.kind) || !hasSameQueueScope(firstQueuedItem, item)) {
|
|
82966
82949
|
break;
|
|
82967
82950
|
}
|
|
82951
|
+
if (firstQueuedItem.kind === "task_notification" && item.kind !== "task_notification" || firstQueuedItem.kind !== "task_notification" && item.kind === "task_notification") {
|
|
82952
|
+
break;
|
|
82953
|
+
}
|
|
82968
82954
|
queueLen += 1;
|
|
82969
82955
|
if (item.kind === "message") {
|
|
82970
82956
|
hasMessage = true;
|
|
@@ -83674,6 +83660,18 @@ function isListMemoryCommand(value) {
|
|
|
83674
83660
|
const c = value;
|
|
83675
83661
|
return c.type === "list_memory" && typeof c.request_id === "string" && typeof c.agent_id === "string";
|
|
83676
83662
|
}
|
|
83663
|
+
function isMemoryHistoryCommand(value) {
|
|
83664
|
+
if (!value || typeof value !== "object")
|
|
83665
|
+
return false;
|
|
83666
|
+
const c = value;
|
|
83667
|
+
return c.type === "memory_history" && typeof c.request_id === "string" && typeof c.agent_id === "string" && typeof c.file_path === "string";
|
|
83668
|
+
}
|
|
83669
|
+
function isMemoryFileAtRefCommand(value) {
|
|
83670
|
+
if (!value || typeof value !== "object")
|
|
83671
|
+
return false;
|
|
83672
|
+
const c = value;
|
|
83673
|
+
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";
|
|
83674
|
+
}
|
|
83677
83675
|
function isEnableMemfsCommand(value) {
|
|
83678
83676
|
if (!value || typeof value !== "object")
|
|
83679
83677
|
return false;
|
|
@@ -83786,7 +83784,7 @@ function parseServerMessage(data) {
|
|
|
83786
83784
|
try {
|
|
83787
83785
|
const raw = typeof data === "string" ? data : data.toString();
|
|
83788
83786
|
const parsed = JSON.parse(raw);
|
|
83789
|
-
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)) {
|
|
83787
|
+
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)) {
|
|
83790
83788
|
return parsed;
|
|
83791
83789
|
}
|
|
83792
83790
|
const invalidInput = getInvalidInputReason(parsed);
|
|
@@ -83814,21 +83812,21 @@ __export(exports_memoryScanner, {
|
|
|
83814
83812
|
readFileContent: () => readFileContent,
|
|
83815
83813
|
getFileNodes: () => getFileNodes
|
|
83816
83814
|
});
|
|
83817
|
-
import { readdirSync as
|
|
83818
|
-
import { join as
|
|
83815
|
+
import { readdirSync as readdirSync9, readFileSync as readFileSync12, statSync as statSync7 } from "node:fs";
|
|
83816
|
+
import { join as join26, relative as relative11 } from "node:path";
|
|
83819
83817
|
function scanMemoryFilesystem(memoryRoot) {
|
|
83820
83818
|
const nodes = [];
|
|
83821
83819
|
const scanDir = (dir, depth, parentIsLast) => {
|
|
83822
83820
|
let entries;
|
|
83823
83821
|
try {
|
|
83824
|
-
entries =
|
|
83822
|
+
entries = readdirSync9(dir);
|
|
83825
83823
|
} catch {
|
|
83826
83824
|
return;
|
|
83827
83825
|
}
|
|
83828
83826
|
const filtered = entries.filter((name) => !name.startsWith("."));
|
|
83829
83827
|
const sorted = filtered.sort((a, b) => {
|
|
83830
|
-
const aPath =
|
|
83831
|
-
const bPath =
|
|
83828
|
+
const aPath = join26(dir, a);
|
|
83829
|
+
const bPath = join26(dir, b);
|
|
83832
83830
|
let aIsDir = false;
|
|
83833
83831
|
let bIsDir = false;
|
|
83834
83832
|
try {
|
|
@@ -83848,7 +83846,7 @@ function scanMemoryFilesystem(memoryRoot) {
|
|
|
83848
83846
|
return a.localeCompare(b);
|
|
83849
83847
|
});
|
|
83850
83848
|
sorted.forEach((name, index) => {
|
|
83851
|
-
const fullPath =
|
|
83849
|
+
const fullPath = join26(dir, name);
|
|
83852
83850
|
let isDir = false;
|
|
83853
83851
|
try {
|
|
83854
83852
|
isDir = statSync7(fullPath).isDirectory();
|
|
@@ -83879,7 +83877,7 @@ function getFileNodes(nodes) {
|
|
|
83879
83877
|
}
|
|
83880
83878
|
function readFileContent(fullPath) {
|
|
83881
83879
|
try {
|
|
83882
|
-
return
|
|
83880
|
+
return readFileSync12(fullPath, "utf-8");
|
|
83883
83881
|
} catch {
|
|
83884
83882
|
return "(unable to read file)";
|
|
83885
83883
|
}
|
|
@@ -84085,7 +84083,7 @@ async function applyModelUpdateForRuntime(params) {
|
|
|
84085
84083
|
modelSettings = updatedAgent.model_settings ?? null;
|
|
84086
84084
|
appliedTo = "agent";
|
|
84087
84085
|
} else {
|
|
84088
|
-
const updatedConversation = await updateConversationLLMConfig(conversationId, model.handle, updateArgs);
|
|
84086
|
+
const updatedConversation = await updateConversationLLMConfig(conversationId, model.handle, updateArgs, { preserveContextWindow: false });
|
|
84089
84087
|
modelSettings = updatedConversation.model_settings ?? null;
|
|
84090
84088
|
appliedTo = "conversation";
|
|
84091
84089
|
}
|
|
@@ -84325,19 +84323,19 @@ function emitSkillsUpdated(socket) {
|
|
|
84325
84323
|
}
|
|
84326
84324
|
async function handleSkillCommand(parsed, socket) {
|
|
84327
84325
|
const {
|
|
84328
|
-
existsSync:
|
|
84326
|
+
existsSync: existsSync21,
|
|
84329
84327
|
lstatSync: lstatSync2,
|
|
84330
84328
|
mkdirSync: mkdirSync15,
|
|
84331
84329
|
rmdirSync,
|
|
84332
84330
|
symlinkSync,
|
|
84333
84331
|
unlinkSync: unlinkSync8
|
|
84334
84332
|
} = await import("node:fs");
|
|
84335
|
-
const { basename: basename5, join:
|
|
84336
|
-
const lettaHome = process.env.LETTA_HOME ||
|
|
84337
|
-
const globalSkillsDir =
|
|
84333
|
+
const { basename: basename5, join: join27 } = await import("node:path");
|
|
84334
|
+
const lettaHome = process.env.LETTA_HOME || join27(process.env.HOME || process.env.USERPROFILE || "~", ".letta");
|
|
84335
|
+
const globalSkillsDir = join27(lettaHome, "skills");
|
|
84338
84336
|
if (parsed.type === "skill_enable") {
|
|
84339
84337
|
try {
|
|
84340
|
-
if (!
|
|
84338
|
+
if (!existsSync21(parsed.skill_path)) {
|
|
84341
84339
|
safeSocketSend(socket, {
|
|
84342
84340
|
type: "skill_enable_response",
|
|
84343
84341
|
request_id: parsed.request_id,
|
|
@@ -84346,8 +84344,8 @@ async function handleSkillCommand(parsed, socket) {
|
|
|
84346
84344
|
}, "listener_skill_send_failed", "listener_skill_command");
|
|
84347
84345
|
return true;
|
|
84348
84346
|
}
|
|
84349
|
-
const skillMdPath =
|
|
84350
|
-
if (!
|
|
84347
|
+
const skillMdPath = join27(parsed.skill_path, "SKILL.md");
|
|
84348
|
+
if (!existsSync21(skillMdPath)) {
|
|
84351
84349
|
safeSocketSend(socket, {
|
|
84352
84350
|
type: "skill_enable_response",
|
|
84353
84351
|
request_id: parsed.request_id,
|
|
@@ -84357,9 +84355,9 @@ async function handleSkillCommand(parsed, socket) {
|
|
|
84357
84355
|
return true;
|
|
84358
84356
|
}
|
|
84359
84357
|
const linkName = basename5(parsed.skill_path);
|
|
84360
|
-
const linkPath =
|
|
84358
|
+
const linkPath = join27(globalSkillsDir, linkName);
|
|
84361
84359
|
mkdirSync15(globalSkillsDir, { recursive: true });
|
|
84362
|
-
if (
|
|
84360
|
+
if (existsSync21(linkPath)) {
|
|
84363
84361
|
const stat6 = lstatSync2(linkPath);
|
|
84364
84362
|
if (stat6.isSymbolicLink()) {
|
|
84365
84363
|
if (process.platform === "win32") {
|
|
@@ -84400,8 +84398,8 @@ async function handleSkillCommand(parsed, socket) {
|
|
|
84400
84398
|
}
|
|
84401
84399
|
if (parsed.type === "skill_disable") {
|
|
84402
84400
|
try {
|
|
84403
|
-
const linkPath =
|
|
84404
|
-
if (!
|
|
84401
|
+
const linkPath = join27(globalSkillsDir, parsed.name);
|
|
84402
|
+
if (!existsSync21(linkPath)) {
|
|
84405
84403
|
safeSocketSend(socket, {
|
|
84406
84404
|
type: "skill_disable_response",
|
|
84407
84405
|
request_id: parsed.request_id,
|
|
@@ -84932,8 +84930,8 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
84932
84930
|
const delay = Math.min(INITIAL_RETRY_DELAY_MS * 2 ** (attempt - 1), MAX_RETRY_DELAY_MS);
|
|
84933
84931
|
const maxAttempts = Math.ceil(Math.log2(MAX_RETRY_DURATION_MS / INITIAL_RETRY_DELAY_MS));
|
|
84934
84932
|
opts.onRetrying?.(attempt, maxAttempts, delay, opts.connectionId);
|
|
84935
|
-
await new Promise((
|
|
84936
|
-
runtime.reconnectTimeout = setTimeout(
|
|
84933
|
+
await new Promise((resolve24) => {
|
|
84934
|
+
runtime.reconnectTimeout = setTimeout(resolve24, delay);
|
|
84937
84935
|
});
|
|
84938
84936
|
runtime.reconnectTimeout = null;
|
|
84939
84937
|
if (runtime !== getActiveRuntime() || runtime.intentionallyClosed) {
|
|
@@ -85187,11 +85185,17 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
85187
85185
|
if (isSearchFilesCommand(parsed)) {
|
|
85188
85186
|
runDetachedListenerTask("search_files", async () => {
|
|
85189
85187
|
try {
|
|
85188
|
+
if (parsed.cwd) {
|
|
85189
|
+
const currentRoot = getIndexRoot();
|
|
85190
|
+
if (!parsed.cwd.startsWith(currentRoot + path22.sep) && parsed.cwd !== currentRoot) {
|
|
85191
|
+
setIndexRoot(parsed.cwd);
|
|
85192
|
+
}
|
|
85193
|
+
}
|
|
85190
85194
|
await ensureFileIndex2();
|
|
85191
85195
|
let searchDir = ".";
|
|
85192
85196
|
if (parsed.cwd) {
|
|
85193
85197
|
const rel = path22.relative(getIndexRoot(), parsed.cwd);
|
|
85194
|
-
if (rel && !rel.startsWith("..")) {
|
|
85198
|
+
if (rel && !rel.startsWith("..") && rel !== "") {
|
|
85195
85199
|
searchDir = rel;
|
|
85196
85200
|
}
|
|
85197
85201
|
}
|
|
@@ -85381,10 +85385,10 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
85381
85385
|
const { getMemoryFilesystemRoot: getMemoryFilesystemRoot2 } = await Promise.resolve().then(() => (init_memoryFilesystem(), exports_memoryFilesystem));
|
|
85382
85386
|
const { scanMemoryFilesystem: scanMemoryFilesystem2, getFileNodes: getFileNodes2, readFileContent: readFileContent2 } = await Promise.resolve().then(() => (init_memoryScanner(), exports_memoryScanner));
|
|
85383
85387
|
const { parseFrontmatter: parseFrontmatter2 } = await Promise.resolve().then(() => exports_frontmatter);
|
|
85384
|
-
const { existsSync:
|
|
85385
|
-
const { join:
|
|
85388
|
+
const { existsSync: existsSync21 } = await import("node:fs");
|
|
85389
|
+
const { join: join27 } = await import("node:path");
|
|
85386
85390
|
const memoryRoot = getMemoryFilesystemRoot2(parsed.agent_id);
|
|
85387
|
-
const memfsInitialized =
|
|
85391
|
+
const memfsInitialized = existsSync21(join27(memoryRoot, ".git"));
|
|
85388
85392
|
if (!memfsInitialized) {
|
|
85389
85393
|
safeSocketSend(socket, {
|
|
85390
85394
|
type: "list_memory_response",
|
|
@@ -85541,6 +85545,72 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
|
|
|
85541
85545
|
});
|
|
85542
85546
|
return;
|
|
85543
85547
|
}
|
|
85548
|
+
if (isMemoryHistoryCommand(parsed)) {
|
|
85549
|
+
runDetachedListenerTask("memory_history", async () => {
|
|
85550
|
+
const { getMemoryFilesystemRoot: getMemoryFilesystemRoot2 } = await Promise.resolve().then(() => (init_memoryFilesystem(), exports_memoryFilesystem));
|
|
85551
|
+
const { execFile: execFileCb5 } = await import("node:child_process");
|
|
85552
|
+
const { promisify: promisify13 } = await import("node:util");
|
|
85553
|
+
const execFileAsync7 = promisify13(execFileCb5);
|
|
85554
|
+
const memoryRoot = getMemoryFilesystemRoot2(parsed.agent_id);
|
|
85555
|
+
const limit2 = parsed.limit ?? 50;
|
|
85556
|
+
const { stdout } = await execFileAsync7("git", [
|
|
85557
|
+
"log",
|
|
85558
|
+
`--max-count=${limit2}`,
|
|
85559
|
+
"--format=%H|%s|%aI|%an",
|
|
85560
|
+
"--",
|
|
85561
|
+
parsed.file_path
|
|
85562
|
+
], { cwd: memoryRoot, timeout: 1e4 });
|
|
85563
|
+
const commits = stdout.trim().split(`
|
|
85564
|
+
`).filter((line) => line.length > 0).map((line) => {
|
|
85565
|
+
const [sha, message, timestamp, authorName] = line.split("|");
|
|
85566
|
+
return {
|
|
85567
|
+
sha: sha ?? "",
|
|
85568
|
+
message: message ?? "",
|
|
85569
|
+
timestamp: timestamp ?? "",
|
|
85570
|
+
author_name: authorName ?? null
|
|
85571
|
+
};
|
|
85572
|
+
});
|
|
85573
|
+
safeSocketSend(socket, {
|
|
85574
|
+
type: "memory_history_response",
|
|
85575
|
+
request_id: parsed.request_id,
|
|
85576
|
+
file_path: parsed.file_path,
|
|
85577
|
+
commits,
|
|
85578
|
+
success: true
|
|
85579
|
+
}, "listener_memory_history_send_failed", "listener_memory_history");
|
|
85580
|
+
});
|
|
85581
|
+
return;
|
|
85582
|
+
}
|
|
85583
|
+
if (isMemoryFileAtRefCommand(parsed)) {
|
|
85584
|
+
runDetachedListenerTask("memory_file_at_ref", async () => {
|
|
85585
|
+
const { getMemoryFilesystemRoot: getMemoryFilesystemRoot2 } = await Promise.resolve().then(() => (init_memoryFilesystem(), exports_memoryFilesystem));
|
|
85586
|
+
const { execFile: execFileCb5 } = await import("node:child_process");
|
|
85587
|
+
const { promisify: promisify13 } = await import("node:util");
|
|
85588
|
+
const execFileAsync7 = promisify13(execFileCb5);
|
|
85589
|
+
const memoryRoot = getMemoryFilesystemRoot2(parsed.agent_id);
|
|
85590
|
+
try {
|
|
85591
|
+
const { stdout } = await execFileAsync7("git", ["show", `${parsed.ref}:${parsed.file_path}`], { cwd: memoryRoot, timeout: 1e4 });
|
|
85592
|
+
safeSocketSend(socket, {
|
|
85593
|
+
type: "memory_file_at_ref_response",
|
|
85594
|
+
request_id: parsed.request_id,
|
|
85595
|
+
file_path: parsed.file_path,
|
|
85596
|
+
ref: parsed.ref,
|
|
85597
|
+
content: stdout,
|
|
85598
|
+
success: true
|
|
85599
|
+
}, "listener_memory_file_at_ref_send_failed", "listener_memory_file_at_ref");
|
|
85600
|
+
} catch (err) {
|
|
85601
|
+
safeSocketSend(socket, {
|
|
85602
|
+
type: "memory_file_at_ref_response",
|
|
85603
|
+
request_id: parsed.request_id,
|
|
85604
|
+
file_path: parsed.file_path,
|
|
85605
|
+
ref: parsed.ref,
|
|
85606
|
+
content: null,
|
|
85607
|
+
success: false,
|
|
85608
|
+
error: err instanceof Error ? err.message : "Failed to read file at ref"
|
|
85609
|
+
}, "listener_memory_file_at_ref_send_failed", "listener_memory_file_at_ref");
|
|
85610
|
+
}
|
|
85611
|
+
});
|
|
85612
|
+
return;
|
|
85613
|
+
}
|
|
85544
85614
|
if (isCronListCommand(parsed) || isCronAddCommand(parsed) || isCronGetCommand(parsed) || isCronDeleteCommand(parsed) || isCronDeleteAllCommand(parsed)) {
|
|
85545
85615
|
runDetachedListenerTask("cron_command", async () => {
|
|
85546
85616
|
await handleCronCommand(parsed, socket);
|
|
@@ -86070,14 +86140,14 @@ __export(exports_debug2, {
|
|
|
86070
86140
|
});
|
|
86071
86141
|
import {
|
|
86072
86142
|
appendFileSync as appendFileSync3,
|
|
86073
|
-
existsSync as
|
|
86143
|
+
existsSync as existsSync22,
|
|
86074
86144
|
mkdirSync as mkdirSync16,
|
|
86075
|
-
readdirSync as
|
|
86076
|
-
readFileSync as
|
|
86145
|
+
readdirSync as readdirSync10,
|
|
86146
|
+
readFileSync as readFileSync13,
|
|
86077
86147
|
unlinkSync as unlinkSync8
|
|
86078
86148
|
} from "node:fs";
|
|
86079
86149
|
import { homedir as homedir26 } from "node:os";
|
|
86080
|
-
import { join as
|
|
86150
|
+
import { join as join30 } from "node:path";
|
|
86081
86151
|
import { format as format2 } from "node:util";
|
|
86082
86152
|
function isDebugEnabled2() {
|
|
86083
86153
|
const lettaDebug = process.env.LETTA_DEBUG;
|
|
@@ -86108,8 +86178,8 @@ class DebugLogFile2 {
|
|
|
86108
86178
|
const telem = process.env.LETTA_CODE_TELEM;
|
|
86109
86179
|
if (telem === "0" || telem === "false")
|
|
86110
86180
|
return;
|
|
86111
|
-
this.agentDir =
|
|
86112
|
-
this.logPath =
|
|
86181
|
+
this.agentDir = join30(DEBUG_LOG_DIR2, agentId);
|
|
86182
|
+
this.logPath = join30(this.agentDir, `${sessionId}.log`);
|
|
86113
86183
|
this.dirCreated = false;
|
|
86114
86184
|
this.pruneOldSessions();
|
|
86115
86185
|
}
|
|
@@ -86125,9 +86195,9 @@ class DebugLogFile2 {
|
|
|
86125
86195
|
if (!this.logPath)
|
|
86126
86196
|
return;
|
|
86127
86197
|
try {
|
|
86128
|
-
if (!
|
|
86198
|
+
if (!existsSync22(this.logPath))
|
|
86129
86199
|
return;
|
|
86130
|
-
const content =
|
|
86200
|
+
const content = readFileSync13(this.logPath, "utf8");
|
|
86131
86201
|
const lines = content.trimEnd().split(`
|
|
86132
86202
|
`);
|
|
86133
86203
|
return lines.slice(-maxLines).join(`
|
|
@@ -86140,7 +86210,7 @@ class DebugLogFile2 {
|
|
|
86140
86210
|
if (this.dirCreated || !this.agentDir)
|
|
86141
86211
|
return;
|
|
86142
86212
|
try {
|
|
86143
|
-
if (!
|
|
86213
|
+
if (!existsSync22(this.agentDir)) {
|
|
86144
86214
|
mkdirSync16(this.agentDir, { recursive: true });
|
|
86145
86215
|
}
|
|
86146
86216
|
this.dirCreated = true;
|
|
@@ -86150,14 +86220,14 @@ class DebugLogFile2 {
|
|
|
86150
86220
|
if (!this.agentDir)
|
|
86151
86221
|
return;
|
|
86152
86222
|
try {
|
|
86153
|
-
if (!
|
|
86223
|
+
if (!existsSync22(this.agentDir))
|
|
86154
86224
|
return;
|
|
86155
|
-
const files =
|
|
86225
|
+
const files = readdirSync10(this.agentDir).filter((f) => f.endsWith(".log")).sort();
|
|
86156
86226
|
if (files.length >= MAX_SESSION_FILES3) {
|
|
86157
86227
|
const toDelete = files.slice(0, files.length - MAX_SESSION_FILES3 + 1);
|
|
86158
86228
|
for (const file of toDelete) {
|
|
86159
86229
|
try {
|
|
86160
|
-
unlinkSync8(
|
|
86230
|
+
unlinkSync8(join30(this.agentDir, file));
|
|
86161
86231
|
} catch {}
|
|
86162
86232
|
}
|
|
86163
86233
|
}
|
|
@@ -86182,7 +86252,7 @@ function debugWarn2(prefix, message, ...args) {
|
|
|
86182
86252
|
}
|
|
86183
86253
|
var DEBUG_LOG_DIR2, MAX_SESSION_FILES3 = 5, DEFAULT_TAIL_LINES2 = 50, debugLogFile2;
|
|
86184
86254
|
var init_debug2 = __esm(() => {
|
|
86185
|
-
DEBUG_LOG_DIR2 =
|
|
86255
|
+
DEBUG_LOG_DIR2 = join30(homedir26(), ".letta", "logs", "debug");
|
|
86186
86256
|
debugLogFile2 = new DebugLogFile2;
|
|
86187
86257
|
});
|
|
86188
86258
|
|
|
@@ -86209,22 +86279,22 @@ __export(exports_skills2, {
|
|
|
86209
86279
|
SKILLS_DIR: () => SKILLS_DIR2,
|
|
86210
86280
|
GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR2
|
|
86211
86281
|
});
|
|
86212
|
-
import { existsSync as
|
|
86282
|
+
import { existsSync as existsSync23 } from "node:fs";
|
|
86213
86283
|
import { readdir as readdir7, readFile as readFile8, realpath as realpath4, stat as stat6 } from "node:fs/promises";
|
|
86214
|
-
import { dirname as dirname13, join as
|
|
86284
|
+
import { dirname as dirname13, join as join31 } from "node:path";
|
|
86215
86285
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
86216
86286
|
function getBundledSkillsPath2() {
|
|
86217
86287
|
const thisDir = dirname13(fileURLToPath8(import.meta.url));
|
|
86218
86288
|
if (thisDir.includes("src/agent") || thisDir.includes("src\\agent")) {
|
|
86219
|
-
return
|
|
86289
|
+
return join31(thisDir, "../skills/builtin");
|
|
86220
86290
|
}
|
|
86221
|
-
return
|
|
86291
|
+
return join31(thisDir, "skills");
|
|
86222
86292
|
}
|
|
86223
86293
|
function compareSkills2(a, b) {
|
|
86224
86294
|
return a.id.localeCompare(b.id) || a.source.localeCompare(b.source) || a.path.localeCompare(b.path);
|
|
86225
86295
|
}
|
|
86226
86296
|
function getAgentSkillsDir2(agentId) {
|
|
86227
|
-
return
|
|
86297
|
+
return join31(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "skills");
|
|
86228
86298
|
}
|
|
86229
86299
|
async function getBundledSkills2() {
|
|
86230
86300
|
const bundledPath = getBundledSkillsPath2();
|
|
@@ -86233,7 +86303,7 @@ async function getBundledSkills2() {
|
|
|
86233
86303
|
}
|
|
86234
86304
|
async function discoverSkillsFromDir2(skillsPath, source) {
|
|
86235
86305
|
const errors = [];
|
|
86236
|
-
if (!
|
|
86306
|
+
if (!existsSync23(skillsPath)) {
|
|
86237
86307
|
return { skills: [], errors: [] };
|
|
86238
86308
|
}
|
|
86239
86309
|
const skills = [];
|
|
@@ -86247,7 +86317,7 @@ async function discoverSkillsFromDir2(skillsPath, source) {
|
|
|
86247
86317
|
}
|
|
86248
86318
|
return { skills, errors };
|
|
86249
86319
|
}
|
|
86250
|
-
async function discoverSkills2(projectSkillsPath =
|
|
86320
|
+
async function discoverSkills2(projectSkillsPath = join31(process.cwd(), SKILLS_DIR2), agentId, options) {
|
|
86251
86321
|
const allErrors = [];
|
|
86252
86322
|
const skillsById = new Map;
|
|
86253
86323
|
const sourceSet = new Set(options?.sources ?? ALL_SKILL_SOURCES);
|
|
@@ -86302,7 +86372,7 @@ async function findSkillFiles2(currentPath, rootPath, skills, errors, source, vi
|
|
|
86302
86372
|
try {
|
|
86303
86373
|
const entries = await readdir7(currentPath, { withFileTypes: true });
|
|
86304
86374
|
for (const entry of entries) {
|
|
86305
|
-
const fullPath =
|
|
86375
|
+
const fullPath = join31(currentPath, entry.name);
|
|
86306
86376
|
try {
|
|
86307
86377
|
let isDirectory = entry.isDirectory();
|
|
86308
86378
|
let isFile = entry.isFile();
|
|
@@ -86391,7 +86461,7 @@ ${lines.join(`
|
|
|
86391
86461
|
var SKILLS_DIR2 = ".skills", GLOBAL_SKILLS_DIR2;
|
|
86392
86462
|
var init_skills2 = __esm(() => {
|
|
86393
86463
|
init_skillSources();
|
|
86394
|
-
GLOBAL_SKILLS_DIR2 =
|
|
86464
|
+
GLOBAL_SKILLS_DIR2 = join31(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
|
|
86395
86465
|
});
|
|
86396
86466
|
|
|
86397
86467
|
// src/utils/fs.ts
|
|
@@ -86405,7 +86475,7 @@ __export(exports_fs, {
|
|
|
86405
86475
|
exists: () => exists2
|
|
86406
86476
|
});
|
|
86407
86477
|
import {
|
|
86408
|
-
existsSync as
|
|
86478
|
+
existsSync as existsSync24,
|
|
86409
86479
|
readFileSync as fsReadFileSync2,
|
|
86410
86480
|
writeFileSync as fsWriteFileSync2,
|
|
86411
86481
|
mkdirSync as mkdirSync17
|
|
@@ -86416,13 +86486,13 @@ async function readFile9(path23) {
|
|
|
86416
86486
|
}
|
|
86417
86487
|
async function writeFile7(path23, content) {
|
|
86418
86488
|
const dir = dirname14(path23);
|
|
86419
|
-
if (!
|
|
86489
|
+
if (!existsSync24(dir)) {
|
|
86420
86490
|
mkdirSync17(dir, { recursive: true });
|
|
86421
86491
|
}
|
|
86422
86492
|
fsWriteFileSync2(path23, content, { encoding: "utf-8", flush: true });
|
|
86423
86493
|
}
|
|
86424
86494
|
function exists2(path23) {
|
|
86425
|
-
return
|
|
86495
|
+
return existsSync24(path23);
|
|
86426
86496
|
}
|
|
86427
86497
|
async function mkdir6(path23, options) {
|
|
86428
86498
|
mkdirSync17(path23, options);
|
|
@@ -86460,7 +86530,7 @@ async function queryTerminalBackground(timeoutMs = 100) {
|
|
|
86460
86530
|
}
|
|
86461
86531
|
const wasRaw = process.stdin.isRaw;
|
|
86462
86532
|
const wasFlowing = process.stdin.readableFlowing;
|
|
86463
|
-
return new Promise((
|
|
86533
|
+
return new Promise((resolve26) => {
|
|
86464
86534
|
let response = "";
|
|
86465
86535
|
let resolved = false;
|
|
86466
86536
|
const cleanup = () => {
|
|
@@ -86477,7 +86547,7 @@ async function queryTerminalBackground(timeoutMs = 100) {
|
|
|
86477
86547
|
};
|
|
86478
86548
|
const timeout = setTimeout(() => {
|
|
86479
86549
|
cleanup();
|
|
86480
|
-
|
|
86550
|
+
resolve26(null);
|
|
86481
86551
|
}, timeoutMs);
|
|
86482
86552
|
const onData = (data) => {
|
|
86483
86553
|
response += data.toString();
|
|
@@ -86487,7 +86557,7 @@ async function queryTerminalBackground(timeoutMs = 100) {
|
|
|
86487
86557
|
if (match3) {
|
|
86488
86558
|
clearTimeout(timeout);
|
|
86489
86559
|
cleanup();
|
|
86490
|
-
|
|
86560
|
+
resolve26({
|
|
86491
86561
|
r: parseHexComponent(match3[1] ?? "0"),
|
|
86492
86562
|
g: parseHexComponent(match3[2] ?? "0"),
|
|
86493
86563
|
b: parseHexComponent(match3[3] ?? "0")
|
|
@@ -86502,7 +86572,7 @@ async function queryTerminalBackground(timeoutMs = 100) {
|
|
|
86502
86572
|
} catch {
|
|
86503
86573
|
clearTimeout(timeout);
|
|
86504
86574
|
cleanup();
|
|
86505
|
-
|
|
86575
|
+
resolve26(null);
|
|
86506
86576
|
}
|
|
86507
86577
|
});
|
|
86508
86578
|
}
|
|
@@ -86553,6 +86623,35 @@ async function initTerminalTheme() {
|
|
|
86553
86623
|
}
|
|
86554
86624
|
var cachedTheme2 = null;
|
|
86555
86625
|
|
|
86626
|
+
// src/agent/bootstrap-tools.ts
|
|
86627
|
+
var exports_bootstrap_tools = {};
|
|
86628
|
+
__export(exports_bootstrap_tools, {
|
|
86629
|
+
bootstrapBaseToolsIfNeeded: () => bootstrapBaseToolsIfNeeded
|
|
86630
|
+
});
|
|
86631
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync18, writeFileSync as writeFileSync12 } from "node:fs";
|
|
86632
|
+
import { homedir as homedir27 } from "node:os";
|
|
86633
|
+
import { join as join32 } from "node:path";
|
|
86634
|
+
async function bootstrapBaseToolsIfNeeded() {
|
|
86635
|
+
if (existsSync25(MARKER_PATH))
|
|
86636
|
+
return;
|
|
86637
|
+
debugLog("bootstrap", "No marker found, bootstrapping base tools...");
|
|
86638
|
+
try {
|
|
86639
|
+
const success = await addBaseToolsToServer();
|
|
86640
|
+
if (success) {
|
|
86641
|
+
mkdirSync18(join32(homedir27(), ".letta"), { recursive: true });
|
|
86642
|
+
writeFileSync12(MARKER_PATH, new Date().toISOString(), "utf-8");
|
|
86643
|
+
}
|
|
86644
|
+
} catch (err) {
|
|
86645
|
+
debugWarn("bootstrap", `Failed to bootstrap base tools: ${err instanceof Error ? err.message : String(err)}`);
|
|
86646
|
+
}
|
|
86647
|
+
}
|
|
86648
|
+
var MARKER_PATH;
|
|
86649
|
+
var init_bootstrap_tools = __esm(async () => {
|
|
86650
|
+
init_debug();
|
|
86651
|
+
await init_create();
|
|
86652
|
+
MARKER_PATH = join32(homedir27(), ".letta", ".bootstrapped");
|
|
86653
|
+
});
|
|
86654
|
+
|
|
86556
86655
|
// src/lsp/manager.ts
|
|
86557
86656
|
var exports_manager2 = {};
|
|
86558
86657
|
__export(exports_manager2, {
|
|
@@ -87270,7 +87369,6 @@ __export(exports_promptAssets2, {
|
|
|
87270
87369
|
MEMORY_PROMPTS: () => MEMORY_PROMPTS2,
|
|
87271
87370
|
MEMORY_CHECK_REMINDER: () => MEMORY_CHECK_REMINDER2,
|
|
87272
87371
|
INTERRUPT_RECOVERY_ALERT: () => INTERRUPT_RECOVERY_ALERT2,
|
|
87273
|
-
AUTO_INIT_REMINDER: () => AUTO_INIT_REMINDER2,
|
|
87274
87372
|
APPROVAL_RECOVERY_PROMPT: () => APPROVAL_RECOVERY_PROMPT2
|
|
87275
87373
|
});
|
|
87276
87374
|
function scanHeadingsOutsideFences2(text) {
|
|
@@ -87401,10 +87499,9 @@ async function resolveSystemPrompt2(systemPromptPreset) {
|
|
|
87401
87499
|
}
|
|
87402
87500
|
throw new Error(`Unknown system prompt "${systemPromptPreset}" — does not match any preset or subagent`);
|
|
87403
87501
|
}
|
|
87404
|
-
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,
|
|
87502
|
+
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;
|
|
87405
87503
|
var init_promptAssets2 = __esm(() => {
|
|
87406
87504
|
init_approval_recovery_alert();
|
|
87407
|
-
init_auto_init_reminder();
|
|
87408
87505
|
init_human();
|
|
87409
87506
|
init_human_kawaii();
|
|
87410
87507
|
init_human_linus();
|
|
@@ -87436,7 +87533,6 @@ var init_promptAssets2 = __esm(() => {
|
|
|
87436
87533
|
REMEMBER_PROMPT2 = remember_default;
|
|
87437
87534
|
MEMORY_CHECK_REMINDER2 = memory_check_reminder_default;
|
|
87438
87535
|
APPROVAL_RECOVERY_PROMPT2 = approval_recovery_alert_default;
|
|
87439
|
-
AUTO_INIT_REMINDER2 = auto_init_reminder_default;
|
|
87440
87536
|
INTERRUPT_RECOVERY_ALERT2 = interrupt_recovery_alert_default;
|
|
87441
87537
|
SLEEPTIME_MEMORY_PERSONA2 = sleeptime_default;
|
|
87442
87538
|
MEMORY_PROMPTS2 = {
|
|
@@ -87711,10 +87807,10 @@ __export(exports_setup, {
|
|
|
87711
87807
|
runSetup: () => runSetup
|
|
87712
87808
|
});
|
|
87713
87809
|
async function runSetup() {
|
|
87714
|
-
return new Promise((
|
|
87810
|
+
return new Promise((resolve27) => {
|
|
87715
87811
|
const { waitUntilExit } = render_default(import_react32.default.createElement(SetupUI, {
|
|
87716
87812
|
onComplete: () => {
|
|
87717
|
-
|
|
87813
|
+
resolve27();
|
|
87718
87814
|
}
|
|
87719
87815
|
}));
|
|
87720
87816
|
waitUntilExit().catch((error) => {
|
|
@@ -88212,8 +88308,8 @@ __export(exports_github_utils, {
|
|
|
88212
88308
|
async function fetchGitHubContents(owner, repo, branch, path25) {
|
|
88213
88309
|
const apiPath = path25 ? `repos/${owner}/${repo}/contents/${path25}?ref=${branch}` : `repos/${owner}/${repo}/contents?ref=${branch}`;
|
|
88214
88310
|
try {
|
|
88215
|
-
const { execSync:
|
|
88216
|
-
const result =
|
|
88311
|
+
const { execSync: execSync2 } = await import("node:child_process");
|
|
88312
|
+
const result = execSync2(`gh api ${apiPath}`, {
|
|
88217
88313
|
encoding: "utf-8",
|
|
88218
88314
|
stdio: ["pipe", "pipe", "ignore"]
|
|
88219
88315
|
});
|
|
@@ -88244,10 +88340,10 @@ __export(exports_import, {
|
|
|
88244
88340
|
});
|
|
88245
88341
|
import { createReadStream } from "node:fs";
|
|
88246
88342
|
import { chmod, mkdir as mkdir7, readFile as readFile10, writeFile as writeFile8 } from "node:fs/promises";
|
|
88247
|
-
import { dirname as dirname15, resolve as
|
|
88343
|
+
import { dirname as dirname15, resolve as resolve27 } from "node:path";
|
|
88248
88344
|
async function importAgentFromFile(options) {
|
|
88249
88345
|
const client = await getClient();
|
|
88250
|
-
const resolvedPath =
|
|
88346
|
+
const resolvedPath = resolve27(options.filePath);
|
|
88251
88347
|
const file = createReadStream(resolvedPath);
|
|
88252
88348
|
const importResponse = await client.agents.importFile({
|
|
88253
88349
|
file,
|
|
@@ -88282,7 +88378,7 @@ async function extractSkillsFromAf(afPath, destDir) {
|
|
|
88282
88378
|
return [];
|
|
88283
88379
|
}
|
|
88284
88380
|
for (const skill2 of afData.skills) {
|
|
88285
|
-
const skillDir =
|
|
88381
|
+
const skillDir = resolve27(destDir, skill2.name);
|
|
88286
88382
|
await mkdir7(skillDir, { recursive: true });
|
|
88287
88383
|
if (skill2.files) {
|
|
88288
88384
|
await writeSkillFiles(skillDir, skill2.files);
|
|
@@ -88302,7 +88398,7 @@ async function writeSkillFiles(skillDir, files) {
|
|
|
88302
88398
|
}
|
|
88303
88399
|
}
|
|
88304
88400
|
async function writeSkillFile(skillDir, filePath, content) {
|
|
88305
|
-
const fullPath =
|
|
88401
|
+
const fullPath = resolve27(skillDir, filePath);
|
|
88306
88402
|
await mkdir7(dirname15(fullPath), { recursive: true });
|
|
88307
88403
|
await writeFile8(fullPath, content, "utf-8");
|
|
88308
88404
|
const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
|
|
@@ -88609,12 +88705,12 @@ async function prepareHeadlessToolExecutionContext(params) {
|
|
|
88609
88705
|
};
|
|
88610
88706
|
}
|
|
88611
88707
|
async function flushAndExit(code) {
|
|
88612
|
-
const flushWritable = (stream2) => new Promise((
|
|
88708
|
+
const flushWritable = (stream2) => new Promise((resolve28) => {
|
|
88613
88709
|
if (stream2.destroyed || stream2.writableEnded) {
|
|
88614
|
-
|
|
88710
|
+
resolve28();
|
|
88615
88711
|
return;
|
|
88616
88712
|
}
|
|
88617
|
-
stream2.write("", () =>
|
|
88713
|
+
stream2.write("", () => resolve28());
|
|
88618
88714
|
});
|
|
88619
88715
|
await Promise.allSettled([
|
|
88620
88716
|
flushWritable(process.stdout),
|
|
@@ -89562,7 +89658,7 @@ ${loadedContents.join(`
|
|
|
89562
89658
|
} else {
|
|
89563
89659
|
console.error(`Conversation is busy, waiting ${Math.round(retryDelayMs / 1000)}s and retrying...`);
|
|
89564
89660
|
}
|
|
89565
|
-
await new Promise((
|
|
89661
|
+
await new Promise((resolve28) => setTimeout(resolve28, retryDelayMs));
|
|
89566
89662
|
continue;
|
|
89567
89663
|
}
|
|
89568
89664
|
}
|
|
@@ -89611,7 +89707,7 @@ ${loadedContents.join(`
|
|
|
89611
89707
|
const delaySeconds = Math.round(delayMs / 1000);
|
|
89612
89708
|
console.error(`Transient API error before streaming (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
89613
89709
|
}
|
|
89614
|
-
await new Promise((
|
|
89710
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
89615
89711
|
conversationBusyRetries = 0;
|
|
89616
89712
|
continue;
|
|
89617
89713
|
}
|
|
@@ -89850,7 +89946,7 @@ ${loadedContents.join(`
|
|
|
89850
89946
|
const delaySeconds = Math.round(delayMs / 1000);
|
|
89851
89947
|
console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
89852
89948
|
}
|
|
89853
|
-
await new Promise((
|
|
89949
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
89854
89950
|
refreshCurrentInputOtids();
|
|
89855
89951
|
continue;
|
|
89856
89952
|
}
|
|
@@ -89940,7 +90036,7 @@ ${loadedContents.join(`
|
|
|
89940
90036
|
} else {
|
|
89941
90037
|
console.error(`Empty LLM response, retrying (attempt ${attempt} of ${EMPTY_RESPONSE_MAX_RETRIES2})...`);
|
|
89942
90038
|
}
|
|
89943
|
-
await new Promise((
|
|
90039
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
89944
90040
|
refreshCurrentInputOtids();
|
|
89945
90041
|
continue;
|
|
89946
90042
|
}
|
|
@@ -89968,7 +90064,7 @@ ${loadedContents.join(`
|
|
|
89968
90064
|
const delaySeconds = Math.round(delayMs / 1000);
|
|
89969
90065
|
console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
89970
90066
|
}
|
|
89971
|
-
await new Promise((
|
|
90067
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
89972
90068
|
refreshCurrentInputOtids();
|
|
89973
90069
|
continue;
|
|
89974
90070
|
}
|
|
@@ -89998,7 +90094,7 @@ ${loadedContents.join(`
|
|
|
89998
90094
|
const delaySeconds = Math.round(delayMs / 1000);
|
|
89999
90095
|
console.error(`LLM API error encountered (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES2}), retrying in ${delaySeconds}s...`);
|
|
90000
90096
|
}
|
|
90001
|
-
await new Promise((
|
|
90097
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
90002
90098
|
refreshCurrentInputOtids();
|
|
90003
90099
|
continue;
|
|
90004
90100
|
}
|
|
@@ -90332,9 +90428,9 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
|
|
|
90332
90428
|
const syntheticUserLine = serializeQueuedMessageAsUserLine(queuedMessage);
|
|
90333
90429
|
maybeNotifyBlocked(syntheticUserLine);
|
|
90334
90430
|
if (lineResolver) {
|
|
90335
|
-
const
|
|
90431
|
+
const resolve28 = lineResolver;
|
|
90336
90432
|
lineResolver = null;
|
|
90337
|
-
|
|
90433
|
+
resolve28(syntheticUserLine);
|
|
90338
90434
|
return;
|
|
90339
90435
|
}
|
|
90340
90436
|
lineQueue.push(syntheticUserLine);
|
|
@@ -90342,9 +90438,9 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
|
|
|
90342
90438
|
rl.on("line", (line) => {
|
|
90343
90439
|
maybeNotifyBlocked(line);
|
|
90344
90440
|
if (lineResolver) {
|
|
90345
|
-
const
|
|
90441
|
+
const resolve28 = lineResolver;
|
|
90346
90442
|
lineResolver = null;
|
|
90347
|
-
|
|
90443
|
+
resolve28(line);
|
|
90348
90444
|
} else {
|
|
90349
90445
|
lineQueue.push(line);
|
|
90350
90446
|
}
|
|
@@ -90353,17 +90449,17 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
|
|
|
90353
90449
|
setMessageQueueAdder(null);
|
|
90354
90450
|
msgQueueRuntime.clear("shutdown");
|
|
90355
90451
|
if (lineResolver) {
|
|
90356
|
-
const
|
|
90452
|
+
const resolve28 = lineResolver;
|
|
90357
90453
|
lineResolver = null;
|
|
90358
|
-
|
|
90454
|
+
resolve28(null);
|
|
90359
90455
|
}
|
|
90360
90456
|
});
|
|
90361
90457
|
async function getNextLine() {
|
|
90362
90458
|
if (lineQueue.length > 0) {
|
|
90363
90459
|
return lineQueue.shift() ?? null;
|
|
90364
90460
|
}
|
|
90365
|
-
return new Promise((
|
|
90366
|
-
lineResolver =
|
|
90461
|
+
return new Promise((resolve28) => {
|
|
90462
|
+
lineResolver = resolve28;
|
|
90367
90463
|
});
|
|
90368
90464
|
}
|
|
90369
90465
|
async function requestPermission(toolCallId, toolName, toolInput) {
|
|
@@ -90867,7 +90963,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
|
|
|
90867
90963
|
uuid: `retry-bidir-${randomUUID8()}`
|
|
90868
90964
|
};
|
|
90869
90965
|
console.log(JSON.stringify(retryMsg));
|
|
90870
|
-
await new Promise((
|
|
90966
|
+
await new Promise((resolve28) => setTimeout(resolve28, delayMs));
|
|
90871
90967
|
continue;
|
|
90872
90968
|
}
|
|
90873
90969
|
throw preStreamError;
|
|
@@ -91163,10 +91259,10 @@ async function detectAndEnableKittyProtocol() {
|
|
|
91163
91259
|
detectionComplete = true;
|
|
91164
91260
|
return;
|
|
91165
91261
|
}
|
|
91166
|
-
return new Promise((
|
|
91262
|
+
return new Promise((resolve28) => {
|
|
91167
91263
|
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
91168
91264
|
detectionComplete = true;
|
|
91169
|
-
|
|
91265
|
+
resolve28();
|
|
91170
91266
|
return;
|
|
91171
91267
|
}
|
|
91172
91268
|
const originalRawMode = process.stdin.isRaw;
|
|
@@ -91199,7 +91295,7 @@ async function detectAndEnableKittyProtocol() {
|
|
|
91199
91295
|
console.error("[kitty] protocol query unsupported; enabled anyway (best-effort)");
|
|
91200
91296
|
}
|
|
91201
91297
|
detectionComplete = true;
|
|
91202
|
-
|
|
91298
|
+
resolve28();
|
|
91203
91299
|
};
|
|
91204
91300
|
const handleData = (data) => {
|
|
91205
91301
|
if (timeoutId === undefined) {
|
|
@@ -91557,10 +91653,10 @@ __export(exports_settings, {
|
|
|
91557
91653
|
loadProjectSettings: () => loadProjectSettings,
|
|
91558
91654
|
getSetting: () => getSetting
|
|
91559
91655
|
});
|
|
91560
|
-
import { homedir as
|
|
91656
|
+
import { homedir as homedir30 } from "node:os";
|
|
91561
91657
|
import { join as join36 } from "node:path";
|
|
91562
91658
|
function getSettingsPath() {
|
|
91563
|
-
return join36(
|
|
91659
|
+
return join36(homedir30(), ".letta", "settings.json");
|
|
91564
91660
|
}
|
|
91565
91661
|
async function loadSettings() {
|
|
91566
91662
|
const settingsPath = getSettingsPath();
|
|
@@ -111110,8 +111206,8 @@ html.dark .agent-name { color: var(--text-dim); }
|
|
|
111110
111206
|
var init_plan_viewer_template = () => {};
|
|
111111
111207
|
|
|
111112
111208
|
// src/web/generate-plan-viewer.ts
|
|
111113
|
-
import { chmodSync as chmodSync2, existsSync as existsSync28, mkdirSync as
|
|
111114
|
-
import { homedir as
|
|
111209
|
+
import { chmodSync as chmodSync2, existsSync as existsSync28, mkdirSync as mkdirSync21, writeFileSync as writeFileSync15 } from "node:fs";
|
|
111210
|
+
import { homedir as homedir31 } from "node:os";
|
|
111115
111211
|
import { join as join37 } from "node:path";
|
|
111116
111212
|
async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
|
|
111117
111213
|
const data = {
|
|
@@ -111123,13 +111219,13 @@ async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
|
|
|
111123
111219
|
const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
|
|
111124
111220
|
const html = plan_viewer_template_default.replace("<!--LETTA_PLAN_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
111125
111221
|
if (!existsSync28(VIEWERS_DIR)) {
|
|
111126
|
-
|
|
111222
|
+
mkdirSync21(VIEWERS_DIR, { recursive: true, mode: 448 });
|
|
111127
111223
|
}
|
|
111128
111224
|
try {
|
|
111129
111225
|
chmodSync2(VIEWERS_DIR, 448);
|
|
111130
111226
|
} catch {}
|
|
111131
111227
|
const filePath = join37(VIEWERS_DIR, "plan.html");
|
|
111132
|
-
|
|
111228
|
+
writeFileSync15(filePath, html);
|
|
111133
111229
|
chmodSync2(filePath, 384);
|
|
111134
111230
|
const skipOpen = Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
|
|
111135
111231
|
if (!skipOpen) {
|
|
@@ -111145,7 +111241,7 @@ async function generateAndOpenPlanViewer(planContent, planFilePath, options) {
|
|
|
111145
111241
|
var VIEWERS_DIR;
|
|
111146
111242
|
var init_generate_plan_viewer = __esm(() => {
|
|
111147
111243
|
init_plan_viewer_template();
|
|
111148
|
-
VIEWERS_DIR = join37(
|
|
111244
|
+
VIEWERS_DIR = join37(homedir31(), ".letta", "viewers");
|
|
111149
111245
|
});
|
|
111150
111246
|
|
|
111151
111247
|
// src/cli/components/StaticPlanApproval.tsx
|
|
@@ -113383,9 +113479,9 @@ var init_pasteRegistry = __esm(() => {
|
|
|
113383
113479
|
|
|
113384
113480
|
// src/cli/helpers/clipboard.ts
|
|
113385
113481
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
113386
|
-
import { existsSync as existsSync29, readFileSync as
|
|
113482
|
+
import { existsSync as existsSync29, readFileSync as readFileSync15, statSync as statSync10, unlinkSync as unlinkSync10 } from "node:fs";
|
|
113387
113483
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
113388
|
-
import { basename as basename5, extname as extname5, isAbsolute as isAbsolute19, join as join38, resolve as
|
|
113484
|
+
import { basename as basename5, extname as extname5, isAbsolute as isAbsolute19, join as join38, resolve as resolve28 } from "node:path";
|
|
113389
113485
|
function countLines2(text) {
|
|
113390
113486
|
return (text.match(/\r\n|\r|\n/g) || []).length + 1;
|
|
113391
113487
|
}
|
|
@@ -113433,10 +113529,10 @@ function translatePasteForImages(paste) {
|
|
|
113433
113529
|
} catch {}
|
|
113434
113530
|
}
|
|
113435
113531
|
if (!isAbsolute19(filePath))
|
|
113436
|
-
filePath =
|
|
113532
|
+
filePath = resolve28(process.cwd(), filePath);
|
|
113437
113533
|
const ext3 = extname5(filePath || "").toLowerCase();
|
|
113438
113534
|
if (IMAGE_EXTS.has(ext3) && existsSync29(filePath) && statSync10(filePath).isFile()) {
|
|
113439
|
-
const buf =
|
|
113535
|
+
const buf = readFileSync15(filePath);
|
|
113440
113536
|
const b64 = buf.toString("base64");
|
|
113441
113537
|
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";
|
|
113442
113538
|
const id = allocateImage({
|
|
@@ -113496,7 +113592,7 @@ async function tryImportClipboardImageMac() {
|
|
|
113496
113592
|
return null;
|
|
113497
113593
|
const { tempPath, uti } = clipboardResult;
|
|
113498
113594
|
try {
|
|
113499
|
-
const buffer =
|
|
113595
|
+
const buffer = readFileSync15(tempPath);
|
|
113500
113596
|
try {
|
|
113501
113597
|
unlinkSync10(tempPath);
|
|
113502
113598
|
} catch {}
|
|
@@ -114204,11 +114300,11 @@ __export(exports_terminalKeybindingInstaller, {
|
|
|
114204
114300
|
import {
|
|
114205
114301
|
copyFileSync,
|
|
114206
114302
|
existsSync as existsSync30,
|
|
114207
|
-
mkdirSync as
|
|
114208
|
-
readFileSync as
|
|
114209
|
-
writeFileSync as
|
|
114303
|
+
mkdirSync as mkdirSync22,
|
|
114304
|
+
readFileSync as readFileSync16,
|
|
114305
|
+
writeFileSync as writeFileSync16
|
|
114210
114306
|
} from "node:fs";
|
|
114211
|
-
import { homedir as
|
|
114307
|
+
import { homedir as homedir32, platform as platform5 } from "node:os";
|
|
114212
114308
|
import { dirname as dirname16, join as join39 } from "node:path";
|
|
114213
114309
|
function detectTerminalType() {
|
|
114214
114310
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
@@ -114241,7 +114337,7 @@ function getKeybindingsPath(terminal) {
|
|
|
114241
114337
|
}[terminal];
|
|
114242
114338
|
const os7 = platform5();
|
|
114243
114339
|
if (os7 === "darwin") {
|
|
114244
|
-
return join39(
|
|
114340
|
+
return join39(homedir32(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
114245
114341
|
}
|
|
114246
114342
|
if (os7 === "win32") {
|
|
114247
114343
|
const appData = process.env.APPDATA;
|
|
@@ -114250,7 +114346,7 @@ function getKeybindingsPath(terminal) {
|
|
|
114250
114346
|
return join39(appData, appName, "User", "keybindings.json");
|
|
114251
114347
|
}
|
|
114252
114348
|
if (os7 === "linux") {
|
|
114253
|
-
return join39(
|
|
114349
|
+
return join39(homedir32(), ".config", appName, "User", "keybindings.json");
|
|
114254
114350
|
}
|
|
114255
114351
|
return null;
|
|
114256
114352
|
}
|
|
@@ -114275,7 +114371,7 @@ function keybindingExists(keybindingsPath) {
|
|
|
114275
114371
|
if (!existsSync30(keybindingsPath))
|
|
114276
114372
|
return false;
|
|
114277
114373
|
try {
|
|
114278
|
-
const content =
|
|
114374
|
+
const content = readFileSync16(keybindingsPath, { encoding: "utf-8" });
|
|
114279
114375
|
const keybindings = parseKeybindings(content);
|
|
114280
114376
|
if (!keybindings)
|
|
114281
114377
|
return false;
|
|
@@ -114302,13 +114398,13 @@ function installKeybinding(keybindingsPath) {
|
|
|
114302
114398
|
}
|
|
114303
114399
|
const parentDir = dirname16(keybindingsPath);
|
|
114304
114400
|
if (!existsSync30(parentDir)) {
|
|
114305
|
-
|
|
114401
|
+
mkdirSync22(parentDir, { recursive: true });
|
|
114306
114402
|
}
|
|
114307
114403
|
let keybindings = [];
|
|
114308
114404
|
let backupPath = null;
|
|
114309
114405
|
if (existsSync30(keybindingsPath)) {
|
|
114310
114406
|
backupPath = createBackup(keybindingsPath);
|
|
114311
|
-
const content =
|
|
114407
|
+
const content = readFileSync16(keybindingsPath, { encoding: "utf-8" });
|
|
114312
114408
|
const parsed = parseKeybindings(content);
|
|
114313
114409
|
if (parsed === null) {
|
|
114314
114410
|
return {
|
|
@@ -114321,7 +114417,7 @@ function installKeybinding(keybindingsPath) {
|
|
|
114321
114417
|
keybindings.push(SHIFT_ENTER_KEYBINDING);
|
|
114322
114418
|
const newContent = `${JSON.stringify(keybindings, null, 2)}
|
|
114323
114419
|
`;
|
|
114324
|
-
|
|
114420
|
+
writeFileSync16(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
114325
114421
|
return {
|
|
114326
114422
|
success: true,
|
|
114327
114423
|
backupPath: backupPath ?? undefined
|
|
@@ -114339,7 +114435,7 @@ function removeKeybinding(keybindingsPath) {
|
|
|
114339
114435
|
if (!existsSync30(keybindingsPath)) {
|
|
114340
114436
|
return { success: true };
|
|
114341
114437
|
}
|
|
114342
|
-
const content =
|
|
114438
|
+
const content = readFileSync16(keybindingsPath, { encoding: "utf-8" });
|
|
114343
114439
|
const keybindings = parseKeybindings(content);
|
|
114344
114440
|
if (!keybindings) {
|
|
114345
114441
|
return {
|
|
@@ -114350,7 +114446,7 @@ function removeKeybinding(keybindingsPath) {
|
|
|
114350
114446
|
const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
|
|
114351
114447
|
const newContent = `${JSON.stringify(filtered, null, 2)}
|
|
114352
114448
|
`;
|
|
114353
|
-
|
|
114449
|
+
writeFileSync16(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
114354
114450
|
return { success: true };
|
|
114355
114451
|
} catch (error) {
|
|
114356
114452
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -114407,16 +114503,16 @@ function getWezTermConfigPath() {
|
|
|
114407
114503
|
if (existsSync30(xdgPath))
|
|
114408
114504
|
return xdgPath;
|
|
114409
114505
|
}
|
|
114410
|
-
const configPath = join39(
|
|
114506
|
+
const configPath = join39(homedir32(), ".config", "wezterm", "wezterm.lua");
|
|
114411
114507
|
if (existsSync30(configPath))
|
|
114412
114508
|
return configPath;
|
|
114413
|
-
return join39(
|
|
114509
|
+
return join39(homedir32(), ".wezterm.lua");
|
|
114414
114510
|
}
|
|
114415
114511
|
function wezTermDeleteFixExists(configPath) {
|
|
114416
114512
|
if (!existsSync30(configPath))
|
|
114417
114513
|
return false;
|
|
114418
114514
|
try {
|
|
114419
|
-
const content =
|
|
114515
|
+
const content = readFileSync16(configPath, { encoding: "utf-8" });
|
|
114420
114516
|
return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
|
|
114421
114517
|
} catch {
|
|
114422
114518
|
return false;
|
|
@@ -114433,7 +114529,7 @@ function installWezTermDeleteFix() {
|
|
|
114433
114529
|
if (existsSync30(configPath)) {
|
|
114434
114530
|
backupPath = `${configPath}.letta-backup`;
|
|
114435
114531
|
copyFileSync(configPath, backupPath);
|
|
114436
|
-
content =
|
|
114532
|
+
content = readFileSync16(configPath, { encoding: "utf-8" });
|
|
114437
114533
|
}
|
|
114438
114534
|
if (content.includes("return {") && !content.includes("local config")) {
|
|
114439
114535
|
content = content.replace(/return\s*\{/, "local config = {");
|
|
@@ -114461,9 +114557,9 @@ ${WEZTERM_DELETE_FIX}
|
|
|
114461
114557
|
}
|
|
114462
114558
|
const parentDir = dirname16(configPath);
|
|
114463
114559
|
if (!existsSync30(parentDir)) {
|
|
114464
|
-
|
|
114560
|
+
mkdirSync22(parentDir, { recursive: true });
|
|
114465
114561
|
}
|
|
114466
|
-
|
|
114562
|
+
writeFileSync16(configPath, content, { encoding: "utf-8" });
|
|
114467
114563
|
return {
|
|
114468
114564
|
success: true,
|
|
114469
114565
|
backupPath: backupPath ?? undefined
|
|
@@ -115451,12 +115547,12 @@ var init_HelpDialog = __esm(async () => {
|
|
|
115451
115547
|
});
|
|
115452
115548
|
|
|
115453
115549
|
// src/hooks/writer.ts
|
|
115454
|
-
import { homedir as
|
|
115455
|
-
import { resolve as
|
|
115550
|
+
import { homedir as homedir33 } from "node:os";
|
|
115551
|
+
import { resolve as resolve29 } from "node:path";
|
|
115456
115552
|
function isProjectSettingsPathCollidingWithGlobal2(workingDirectory) {
|
|
115457
|
-
const home = process.env.HOME ||
|
|
115458
|
-
const globalSettingsPath =
|
|
115459
|
-
const projectSettingsPath =
|
|
115553
|
+
const home = process.env.HOME || homedir33();
|
|
115554
|
+
const globalSettingsPath = resolve29(home, ".letta", "settings.json");
|
|
115555
|
+
const projectSettingsPath = resolve29(workingDirectory, ".letta", "settings.json");
|
|
115460
115556
|
return globalSettingsPath === projectSettingsPath;
|
|
115461
115557
|
}
|
|
115462
115558
|
function loadHooksFromLocation(location, workingDirectory = process.cwd()) {
|
|
@@ -118093,14 +118189,14 @@ var init_AgentInfoBar = __esm(async () => {
|
|
|
118093
118189
|
});
|
|
118094
118190
|
|
|
118095
118191
|
// src/cli/helpers/fileSearch.ts
|
|
118096
|
-
import { readdirSync as
|
|
118097
|
-
import { join as join41, relative as relative15, resolve as
|
|
118192
|
+
import { readdirSync as readdirSync12, statSync as statSync11 } from "node:fs";
|
|
118193
|
+
import { join as join41, relative as relative15, resolve as resolve30 } from "node:path";
|
|
118098
118194
|
function searchDirectoryRecursive(dir, pattern, maxResults = 200, results = [], depth = 0, maxDepth = 10, lowerPattern = pattern.toLowerCase()) {
|
|
118099
118195
|
if (results.length >= maxResults || depth >= maxDepth) {
|
|
118100
118196
|
return results;
|
|
118101
118197
|
}
|
|
118102
118198
|
try {
|
|
118103
|
-
const entries =
|
|
118199
|
+
const entries = readdirSync12(dir);
|
|
118104
118200
|
for (const entry of entries) {
|
|
118105
118201
|
try {
|
|
118106
118202
|
const fullPath = join41(dir, entry);
|
|
@@ -118137,7 +118233,7 @@ async function searchFiles(query, deep = false) {
|
|
|
118137
118233
|
const dirPart = query.slice(0, lastSlashIndex);
|
|
118138
118234
|
const pattern = query.slice(lastSlashIndex + 1);
|
|
118139
118235
|
try {
|
|
118140
|
-
const resolvedDir =
|
|
118236
|
+
const resolvedDir = resolve30(getIndexRoot(), dirPart);
|
|
118141
118237
|
try {
|
|
118142
118238
|
statSync11(resolvedDir);
|
|
118143
118239
|
searchDir = resolvedDir;
|
|
@@ -118173,7 +118269,7 @@ async function searchFiles(query, deep = false) {
|
|
|
118173
118269
|
} else {
|
|
118174
118270
|
let entries = [];
|
|
118175
118271
|
try {
|
|
118176
|
-
entries =
|
|
118272
|
+
entries = readdirSync12(searchDir);
|
|
118177
118273
|
} catch {
|
|
118178
118274
|
return [];
|
|
118179
118275
|
}
|
|
@@ -120258,11 +120354,11 @@ var init_InputRich = __esm(async () => {
|
|
|
120258
120354
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
120259
120355
|
import {
|
|
120260
120356
|
existsSync as existsSync32,
|
|
120261
|
-
mkdirSync as
|
|
120357
|
+
mkdirSync as mkdirSync23,
|
|
120262
120358
|
mkdtempSync,
|
|
120263
|
-
readFileSync as
|
|
120359
|
+
readFileSync as readFileSync17,
|
|
120264
120360
|
rmSync as rmSync4,
|
|
120265
|
-
writeFileSync as
|
|
120361
|
+
writeFileSync as writeFileSync17
|
|
120266
120362
|
} from "node:fs";
|
|
120267
120363
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
120268
120364
|
import { dirname as dirname18, join as join42 } from "node:path";
|
|
@@ -120513,17 +120609,17 @@ function runGit6(args, cwd2) {
|
|
|
120513
120609
|
function writeWorkflow(repoDir, workflowPath, content) {
|
|
120514
120610
|
const absolutePath = join42(repoDir, workflowPath);
|
|
120515
120611
|
if (!existsSync32(dirname18(absolutePath))) {
|
|
120516
|
-
|
|
120612
|
+
mkdirSync23(dirname18(absolutePath), { recursive: true });
|
|
120517
120613
|
}
|
|
120518
120614
|
const next = `${content.trimEnd()}
|
|
120519
120615
|
`;
|
|
120520
120616
|
if (existsSync32(absolutePath)) {
|
|
120521
|
-
const previous =
|
|
120617
|
+
const previous = readFileSync17(absolutePath, "utf8");
|
|
120522
120618
|
if (previous === next) {
|
|
120523
120619
|
return false;
|
|
120524
120620
|
}
|
|
120525
120621
|
}
|
|
120526
|
-
|
|
120622
|
+
writeFileSync17(absolutePath, next, "utf8");
|
|
120527
120623
|
return true;
|
|
120528
120624
|
}
|
|
120529
120625
|
function getDefaultBaseBranch(repoDir) {
|
|
@@ -124418,8 +124514,8 @@ __export(exports_generate_memory_viewer, {
|
|
|
124418
124514
|
generateAndOpenMemoryViewer: () => generateAndOpenMemoryViewer
|
|
124419
124515
|
});
|
|
124420
124516
|
import { execFile as execFileCb5 } from "node:child_process";
|
|
124421
|
-
import { chmodSync as chmodSync3, existsSync as existsSync33, mkdirSync as
|
|
124422
|
-
import { homedir as
|
|
124517
|
+
import { chmodSync as chmodSync3, existsSync as existsSync33, mkdirSync as mkdirSync24, writeFileSync as writeFileSync18 } from "node:fs";
|
|
124518
|
+
import { homedir as homedir34 } from "node:os";
|
|
124423
124519
|
import { join as join43 } from "node:path";
|
|
124424
124520
|
import { promisify as promisify14 } from "node:util";
|
|
124425
124521
|
async function runGitSafe(cwd2, args) {
|
|
@@ -124704,13 +124800,13 @@ async function generateAndOpenMemoryViewer(agentId, options) {
|
|
|
124704
124800
|
const jsonPayload = JSON.stringify(data).replace(/</g, "\\u003c");
|
|
124705
124801
|
const html = memory_viewer_template_default.replace("<!--LETTA_DATA_PLACEHOLDER-->", () => jsonPayload);
|
|
124706
124802
|
if (!existsSync33(VIEWERS_DIR2)) {
|
|
124707
|
-
|
|
124803
|
+
mkdirSync24(VIEWERS_DIR2, { recursive: true, mode: 448 });
|
|
124708
124804
|
}
|
|
124709
124805
|
try {
|
|
124710
124806
|
chmodSync3(VIEWERS_DIR2, 448);
|
|
124711
124807
|
} catch {}
|
|
124712
124808
|
const filePath = join43(VIEWERS_DIR2, `memory-${encodeURIComponent(agentId)}.html`);
|
|
124713
|
-
|
|
124809
|
+
writeFileSync18(filePath, html);
|
|
124714
124810
|
chmodSync3(filePath, 384);
|
|
124715
124811
|
const skipOpen = Boolean(process.env.TMUX) || Boolean(process.env.SSH_CONNECTION) || Boolean(process.env.SSH_TTY);
|
|
124716
124812
|
if (!skipOpen) {
|
|
@@ -124733,7 +124829,7 @@ var init_generate_memory_viewer = __esm(async () => {
|
|
|
124733
124829
|
init_memoryGit()
|
|
124734
124830
|
]);
|
|
124735
124831
|
execFile14 = promisify14(execFileCb5);
|
|
124736
|
-
VIEWERS_DIR2 = join43(
|
|
124832
|
+
VIEWERS_DIR2 = join43(homedir34(), ".letta", "viewers");
|
|
124737
124833
|
REFLECTION_PATTERN = /\(reflection\)|🔮|reflection:/i;
|
|
124738
124834
|
});
|
|
124739
124835
|
|
|
@@ -127451,11 +127547,11 @@ var init_PersonalitySelector = __esm(async () => {
|
|
|
127451
127547
|
|
|
127452
127548
|
// src/utils/aws-credentials.ts
|
|
127453
127549
|
import { readFile as readFile12 } from "node:fs/promises";
|
|
127454
|
-
import { homedir as
|
|
127550
|
+
import { homedir as homedir35 } from "node:os";
|
|
127455
127551
|
import { join as join44 } from "node:path";
|
|
127456
127552
|
async function parseAwsCredentials() {
|
|
127457
|
-
const credentialsPath = join44(
|
|
127458
|
-
const configPath = join44(
|
|
127553
|
+
const credentialsPath = join44(homedir35(), ".aws", "credentials");
|
|
127554
|
+
const configPath = join44(homedir35(), ".aws", "config");
|
|
127459
127555
|
const profiles = new Map;
|
|
127460
127556
|
try {
|
|
127461
127557
|
const content = await readFile12(credentialsPath, "utf-8");
|
|
@@ -132555,7 +132651,7 @@ var init_reasoningTabToggle = __esm(() => {
|
|
|
132555
132651
|
});
|
|
132556
132652
|
|
|
132557
132653
|
// src/cli/helpers/startupSystemPromptWarning.ts
|
|
132558
|
-
import { existsSync as existsSync35, readdirSync as
|
|
132654
|
+
import { existsSync as existsSync35, readdirSync as readdirSync13, readFileSync as readFileSync18 } from "node:fs";
|
|
132559
132655
|
import { join as join45 } from "node:path";
|
|
132560
132656
|
function estimateSystemTokens(text) {
|
|
132561
132657
|
return Math.ceil(Buffer.byteLength(text, "utf8") / STARTUP_SYSTEM_PROMPT_ESTIMATED_BYTES_PER_TOKEN);
|
|
@@ -132570,7 +132666,7 @@ function estimateSystemPromptTokensFromMemoryDir(memoryDir) {
|
|
|
132570
132666
|
return [];
|
|
132571
132667
|
}
|
|
132572
132668
|
const out = [];
|
|
132573
|
-
const entries =
|
|
132669
|
+
const entries = readdirSync13(dir, { withFileTypes: true });
|
|
132574
132670
|
for (const entry of entries) {
|
|
132575
132671
|
if (entry.name.startsWith(".")) {
|
|
132576
132672
|
continue;
|
|
@@ -132590,7 +132686,7 @@ function estimateSystemPromptTokensFromMemoryDir(memoryDir) {
|
|
|
132590
132686
|
return out;
|
|
132591
132687
|
};
|
|
132592
132688
|
return walkMarkdownFiles(systemDir).sort().reduce((sum, filePath) => {
|
|
132593
|
-
const text =
|
|
132689
|
+
const text = readFileSync18(filePath, "utf8");
|
|
132594
132690
|
return sum + estimateSystemTokens(text);
|
|
132595
132691
|
}, 0);
|
|
132596
132692
|
}
|
|
@@ -132936,7 +133032,7 @@ async function executeStatusLineCommand(command, payload, options) {
|
|
|
132936
133032
|
};
|
|
132937
133033
|
}
|
|
132938
133034
|
function runWithLauncher(launcher, inputJson, timeout, signal, workingDirectory, startTime) {
|
|
132939
|
-
return new Promise((
|
|
133035
|
+
return new Promise((resolve31, reject) => {
|
|
132940
133036
|
const [executable, ...args] = launcher;
|
|
132941
133037
|
if (!executable) {
|
|
132942
133038
|
reject(new Error("Empty launcher"));
|
|
@@ -132949,7 +133045,7 @@ function runWithLauncher(launcher, inputJson, timeout, signal, workingDirectory,
|
|
|
132949
133045
|
const safeResolve = (result) => {
|
|
132950
133046
|
if (!resolved) {
|
|
132951
133047
|
resolved = true;
|
|
132952
|
-
|
|
133048
|
+
resolve31(result);
|
|
132953
133049
|
}
|
|
132954
133050
|
};
|
|
132955
133051
|
let child;
|
|
@@ -133394,8 +133490,8 @@ __export(exports_shellAliases, {
|
|
|
133394
133490
|
expandAliases: () => expandAliases,
|
|
133395
133491
|
clearAliasCache: () => clearAliasCache
|
|
133396
133492
|
});
|
|
133397
|
-
import { existsSync as existsSync36, readFileSync as
|
|
133398
|
-
import { homedir as
|
|
133493
|
+
import { existsSync as existsSync36, readFileSync as readFileSync19 } from "node:fs";
|
|
133494
|
+
import { homedir as homedir36 } from "node:os";
|
|
133399
133495
|
import { join as join46 } from "node:path";
|
|
133400
133496
|
function parseAliasesFromFile(filePath) {
|
|
133401
133497
|
const aliases = new Map;
|
|
@@ -133403,7 +133499,7 @@ function parseAliasesFromFile(filePath) {
|
|
|
133403
133499
|
return aliases;
|
|
133404
133500
|
}
|
|
133405
133501
|
try {
|
|
133406
|
-
const content =
|
|
133502
|
+
const content = readFileSync19(filePath, "utf-8");
|
|
133407
133503
|
const lines = content.split(`
|
|
133408
133504
|
`);
|
|
133409
133505
|
let inFunction = false;
|
|
@@ -133465,7 +133561,7 @@ function loadAliases(forceReload = false) {
|
|
|
133465
133561
|
if (aliasCache && !forceReload) {
|
|
133466
133562
|
return aliasCache;
|
|
133467
133563
|
}
|
|
133468
|
-
const home =
|
|
133564
|
+
const home = homedir36();
|
|
133469
133565
|
const allAliases = new Map;
|
|
133470
133566
|
for (const file of ALIAS_FILES) {
|
|
133471
133567
|
const filePath = join46(home, file);
|
|
@@ -134126,14 +134222,14 @@ __export(exports_export, {
|
|
|
134126
134222
|
packageSkills: () => packageSkills
|
|
134127
134223
|
});
|
|
134128
134224
|
import { readdir as readdir10, readFile as readFile13 } from "node:fs/promises";
|
|
134129
|
-
import { relative as relative16, resolve as
|
|
134225
|
+
import { relative as relative16, resolve as resolve31 } from "node:path";
|
|
134130
134226
|
async function packageSkills(agentId, skillsDir) {
|
|
134131
134227
|
const skills = [];
|
|
134132
134228
|
const skillNames = new Set;
|
|
134133
134229
|
const dirsToCheck = skillsDir ? [skillsDir] : [
|
|
134134
134230
|
agentId && getAgentSkillsDir(agentId),
|
|
134135
|
-
|
|
134136
|
-
|
|
134231
|
+
resolve31(process.cwd(), ".skills"),
|
|
134232
|
+
resolve31(process.env.HOME || "~", ".letta", "skills")
|
|
134137
134233
|
].filter((dir) => Boolean(dir));
|
|
134138
134234
|
for (const baseDir of dirsToCheck) {
|
|
134139
134235
|
try {
|
|
@@ -134143,8 +134239,8 @@ async function packageSkills(agentId, skillsDir) {
|
|
|
134143
134239
|
continue;
|
|
134144
134240
|
if (skillNames.has(entry.name))
|
|
134145
134241
|
continue;
|
|
134146
|
-
const skillDir =
|
|
134147
|
-
const skillMdPath =
|
|
134242
|
+
const skillDir = resolve31(baseDir, entry.name);
|
|
134243
|
+
const skillMdPath = resolve31(skillDir, "SKILL.md");
|
|
134148
134244
|
try {
|
|
134149
134245
|
await readFile13(skillMdPath, "utf-8");
|
|
134150
134246
|
} catch {
|
|
@@ -134174,7 +134270,7 @@ async function readSkillFiles(skillDir) {
|
|
|
134174
134270
|
async function walk(dir) {
|
|
134175
134271
|
const entries = await readdir10(dir, { withFileTypes: true });
|
|
134176
134272
|
for (const entry of entries) {
|
|
134177
|
-
const fullPath =
|
|
134273
|
+
const fullPath = resolve31(dir, entry.name);
|
|
134178
134274
|
if (entry.isDirectory()) {
|
|
134179
134275
|
await walk(fullPath);
|
|
134180
134276
|
} else {
|
|
@@ -134318,8 +134414,8 @@ __export(exports_App, {
|
|
|
134318
134414
|
default: () => App2
|
|
134319
134415
|
});
|
|
134320
134416
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
134321
|
-
import { existsSync as existsSync37, readFileSync as
|
|
134322
|
-
import { homedir as
|
|
134417
|
+
import { existsSync as existsSync37, readFileSync as readFileSync20, renameSync as renameSync3, writeFileSync as writeFileSync19 } from "node:fs";
|
|
134418
|
+
import { homedir as homedir37, tmpdir as tmpdir6 } from "node:os";
|
|
134323
134419
|
import { join as join47, relative as relative17 } from "node:path";
|
|
134324
134420
|
function deriveReasoningEffort(modelSettings, llmConfig) {
|
|
134325
134421
|
if (modelSettings && "provider_type" in modelSettings) {
|
|
@@ -134583,7 +134679,7 @@ function _readPlanFile(fallbackPlanFilePath) {
|
|
|
134583
134679
|
return `Plan file not found at ${planFilePath}`;
|
|
134584
134680
|
}
|
|
134585
134681
|
try {
|
|
134586
|
-
return
|
|
134682
|
+
return readFileSync20(planFilePath, "utf-8");
|
|
134587
134683
|
} catch {
|
|
134588
134684
|
return `Failed to read plan file at ${planFilePath}`;
|
|
134589
134685
|
}
|
|
@@ -134729,8 +134825,6 @@ function App2({
|
|
|
134729
134825
|
const lastRunIdRef = import_react103.useRef(null);
|
|
134730
134826
|
const resumeKey = useSuspend();
|
|
134731
134827
|
const pendingConversationSwitchRef = import_react103.useRef(null);
|
|
134732
|
-
const autoInitPendingAgentIdsRef = import_react103.useRef(new Set);
|
|
134733
|
-
const startupAutoInitConsumedRef = import_react103.useRef(false);
|
|
134734
134828
|
const prevInitialAgentIdRef = import_react103.useRef(initialAgentId);
|
|
134735
134829
|
const prevInitialAgentStateRef = import_react103.useRef(initialAgentState);
|
|
134736
134830
|
const prevInitialConversationIdRef = import_react103.useRef(initialConversationId);
|
|
@@ -135912,10 +136006,10 @@ function App2({
|
|
|
135912
136006
|
if (!planFilePath)
|
|
135913
136007
|
return;
|
|
135914
136008
|
try {
|
|
135915
|
-
const { readFileSync:
|
|
136009
|
+
const { readFileSync: readFileSync21, existsSync: existsSync38 } = __require("node:fs");
|
|
135916
136010
|
if (!existsSync38(planFilePath))
|
|
135917
136011
|
return;
|
|
135918
|
-
const planContent =
|
|
136012
|
+
const planContent = readFileSync21(planFilePath, "utf-8");
|
|
135919
136013
|
const previewItem = {
|
|
135920
136014
|
kind: "approval_preview",
|
|
135921
136015
|
id: `approval-preview-${toolCallId}`,
|
|
@@ -136231,7 +136325,7 @@ function App2({
|
|
|
136231
136325
|
}
|
|
136232
136326
|
try {
|
|
136233
136327
|
const { updateConversationLLMConfig: updateConversationLLMConfig2 } = await init_modify().then(() => exports_modify);
|
|
136234
|
-
await updateConversationLLMConfig2(targetConversationId, modelHandle, Object.keys(updateArgs).length > 0 ? updateArgs : undefined);
|
|
136328
|
+
await updateConversationLLMConfig2(targetConversationId, modelHandle, Object.keys(updateArgs).length > 0 ? updateArgs : undefined, { preserveContextWindow: true });
|
|
136235
136329
|
} catch (error) {
|
|
136236
136330
|
debugWarn("conversation-model", `Failed to carry over active model to new conversation: ${error instanceof Error ? error.message : String(error)}`);
|
|
136237
136331
|
}
|
|
@@ -136658,7 +136752,7 @@ ${newState.originalPrompt}`,
|
|
|
136658
136752
|
cancelled = true;
|
|
136659
136753
|
break;
|
|
136660
136754
|
}
|
|
136661
|
-
await new Promise((
|
|
136755
|
+
await new Promise((resolve32) => setTimeout(resolve32, 100));
|
|
136662
136756
|
}
|
|
136663
136757
|
buffersRef.current.byId.delete(statusId);
|
|
136664
136758
|
buffersRef.current.order = buffersRef.current.order.filter((id) => id !== statusId);
|
|
@@ -136722,7 +136816,7 @@ ${newState.originalPrompt}`,
|
|
|
136722
136816
|
cancelled = true;
|
|
136723
136817
|
break;
|
|
136724
136818
|
}
|
|
136725
|
-
await new Promise((
|
|
136819
|
+
await new Promise((resolve32) => setTimeout(resolve32, 100));
|
|
136726
136820
|
}
|
|
136727
136821
|
if (retryStatusId) {
|
|
136728
136822
|
buffersRef.current.byId.delete(retryStatusId);
|
|
@@ -137480,7 +137574,7 @@ ${feedback}
|
|
|
137480
137574
|
});
|
|
137481
137575
|
buffersRef.current.order.push(statusId);
|
|
137482
137576
|
refreshDerived();
|
|
137483
|
-
await new Promise((
|
|
137577
|
+
await new Promise((resolve32) => setTimeout(resolve32, delayMs));
|
|
137484
137578
|
buffersRef.current.byId.delete(statusId);
|
|
137485
137579
|
buffersRef.current.order = buffersRef.current.order.filter((id) => id !== statusId);
|
|
137486
137580
|
refreshDerived();
|
|
@@ -137540,7 +137634,7 @@ ${feedback}
|
|
|
137540
137634
|
cancelled = true;
|
|
137541
137635
|
break;
|
|
137542
137636
|
}
|
|
137543
|
-
await new Promise((
|
|
137637
|
+
await new Promise((resolve32) => setTimeout(resolve32, 100));
|
|
137544
137638
|
}
|
|
137545
137639
|
if (retryStatusId) {
|
|
137546
137640
|
buffersRef.current.byId.delete(retryStatusId);
|
|
@@ -138275,14 +138369,11 @@ ${feedback}
|
|
|
138275
138369
|
memoryPromptMode: willAutoEnableMemfs ? "memfs" : undefined
|
|
138276
138370
|
});
|
|
138277
138371
|
await enableMemfsIfCloud2(agent.id);
|
|
138278
|
-
if (settingsManager.isMemfsEnabled(agent.id)) {
|
|
138279
|
-
autoInitPendingAgentIdsRef.current.add(agent.id);
|
|
138280
|
-
}
|
|
138281
138372
|
await updateProjectSettings({ lastAgent: agent.id });
|
|
138282
138373
|
const targetConversationId = "default";
|
|
138283
138374
|
settingsManager.persistSession(agent.id, targetConversationId);
|
|
138284
138375
|
const agentUrl = buildChatUrl(agent.id);
|
|
138285
|
-
const memfsTip =
|
|
138376
|
+
const memfsTip = "Tip: use /init to initialize your agent's memory system!";
|
|
138286
138377
|
const successOutput = [
|
|
138287
138378
|
`Created **${agent.name || agent.id}** (use /pin to save)`,
|
|
138288
138379
|
`⎿ ${agentUrl}`,
|
|
@@ -138730,7 +138821,7 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
|
|
|
138730
138821
|
];
|
|
138731
138822
|
const personaPath = personaCandidates.find((candidate) => existsSync37(candidate));
|
|
138732
138823
|
if (personaPath) {
|
|
138733
|
-
const personaContent =
|
|
138824
|
+
const personaContent = readFileSync20(personaPath, "utf-8");
|
|
138734
138825
|
setCurrentPersonalityId(detectPersonalityFromPersonaFile(personaContent));
|
|
138735
138826
|
} else {
|
|
138736
138827
|
setCurrentPersonalityId(null);
|
|
@@ -139936,7 +140027,7 @@ Press Enter to continue, or type anything to cancel.`, false, "running");
|
|
|
139936
140027
|
fileContent = await client.agents.exportFile(agentId, exportParams);
|
|
139937
140028
|
}
|
|
139938
140029
|
const fileName = exportParams.conversation_id ? `${exportParams.conversation_id}.af` : `${agentId}.af`;
|
|
139939
|
-
|
|
140030
|
+
writeFileSync19(fileName, JSON.stringify(fileContent, null, 2));
|
|
139940
140031
|
let summary = `AgentFile exported to ${fileName}`;
|
|
139941
140032
|
if (skills.length > 0) {
|
|
139942
140033
|
summary += `
|
|
@@ -140229,7 +140320,6 @@ ${SYSTEM_REMINDER_CLOSE}`;
|
|
|
140229
140320
|
cmd.fail("Pending approval(s). Resolve approvals before running /init.");
|
|
140230
140321
|
return { submitted: false };
|
|
140231
140322
|
}
|
|
140232
|
-
autoInitPendingAgentIdsRef.current.delete(agentId);
|
|
140233
140323
|
setCommandRunning(true);
|
|
140234
140324
|
try {
|
|
140235
140325
|
cmd.finish("Building your memory palace... Start a new conversation with `letta --new` to work in parallel.", true);
|
|
@@ -140420,28 +140510,6 @@ ${SYSTEM_REMINDER_CLOSE}`),
|
|
|
140420
140510
|
return { submitted: true };
|
|
140421
140511
|
}
|
|
140422
140512
|
}
|
|
140423
|
-
if (autoInitPendingAgentIdsRef.current.has(agentId) && !isSystemOnly) {
|
|
140424
|
-
try {
|
|
140425
|
-
const fired = await fireAutoInit(agentId, async ({ success, error }) => {
|
|
140426
|
-
const msg2 = await handleMemorySubagentCompletion({
|
|
140427
|
-
agentId,
|
|
140428
|
-
conversationId: conversationIdRef.current,
|
|
140429
|
-
subagentType: "init",
|
|
140430
|
-
success,
|
|
140431
|
-
error
|
|
140432
|
-
}, {
|
|
140433
|
-
recompileByConversation: systemPromptRecompileByConversationRef.current,
|
|
140434
|
-
recompileQueuedByConversation: queuedSystemPromptRecompileByConversationRef.current,
|
|
140435
|
-
logRecompileFailure: (message2) => debugWarn("memory", message2)
|
|
140436
|
-
});
|
|
140437
|
-
appendTaskNotificationEvents([msg2]);
|
|
140438
|
-
});
|
|
140439
|
-
if (fired) {
|
|
140440
|
-
autoInitPendingAgentIdsRef.current.delete(agentId);
|
|
140441
|
-
sharedReminderStateRef.current.pendingAutoInitReminder = true;
|
|
140442
|
-
}
|
|
140443
|
-
} catch {}
|
|
140444
|
-
}
|
|
140445
140513
|
const contentParts = overrideContentParts ?? buildMessageContentFromDisplay(msg);
|
|
140446
140514
|
let ralphModeReminder = "";
|
|
140447
140515
|
if (ralphMode.getState().isActive) {
|
|
@@ -141603,7 +141671,7 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
141603
141671
|
conversationModelSettings = updatedAgent?.model_settings;
|
|
141604
141672
|
} else {
|
|
141605
141673
|
const { updateConversationLLMConfig: updateConversationLLMConfig2 } = await init_modify().then(() => exports_modify);
|
|
141606
|
-
const updatedConversation = await updateConversationLLMConfig2(conversationIdRef.current, modelHandle, model.updateArgs);
|
|
141674
|
+
const updatedConversation = await updateConversationLLMConfig2(conversationIdRef.current, modelHandle, model.updateArgs, { preserveContextWindow: false });
|
|
141607
141675
|
conversationModelSettings = updatedConversation.model_settings;
|
|
141608
141676
|
}
|
|
141609
141677
|
const rawEffort = modelUpdateArgs?.reasoning_effort;
|
|
@@ -142239,7 +142307,7 @@ ${guidance}`);
|
|
|
142239
142307
|
const { updateConversationLLMConfig: updateConversationLLMConfig2 } = await init_modify().then(() => exports_modify);
|
|
142240
142308
|
const updatedConversation = await updateConversationLLMConfig2(conversationIdRef.current, desired.modelHandle, {
|
|
142241
142309
|
reasoning_effort: desired.effort
|
|
142242
|
-
});
|
|
142310
|
+
}, { preserveContextWindow: true });
|
|
142243
142311
|
conversationModelSettings = updatedConversation.model_settings;
|
|
142244
142312
|
}
|
|
142245
142313
|
const resolvedReasoningEffort = deriveReasoningEffort(isDefaultConversation ? updatedAgent?.model_settings ?? null : conversationModelSettings, llmConfigRef.current) ?? desired.effort;
|
|
@@ -142483,7 +142551,7 @@ ${guidance}`);
|
|
|
142483
142551
|
}
|
|
142484
142552
|
if (mode === "bypassPermissions") {
|
|
142485
142553
|
const planFilePath = activePlanPath ?? fallbackPlanPath;
|
|
142486
|
-
const plansDir = join47(
|
|
142554
|
+
const plansDir = join47(homedir37(), ".letta", "plans");
|
|
142487
142555
|
handlePlanKeepPlanning(`You must write your plan to a plan file before exiting plan mode.
|
|
142488
142556
|
` + (planFilePath ? `Plan file path: ${planFilePath}
|
|
142489
142557
|
` : "") + `Use a write tool to create your plan in ${plansDir}, then use ExitPlanMode to present the plan to the user.`);
|
|
@@ -142518,7 +142586,7 @@ ${guidance}`);
|
|
|
142518
142586
|
if (!hasUsablePlan) {
|
|
142519
142587
|
lastAutoHandledExitPlanToolCallIdRef.current = approval.toolCallId;
|
|
142520
142588
|
const planFilePath = activePlanPath ?? fallbackPlanPath;
|
|
142521
|
-
const plansDir = join47(
|
|
142589
|
+
const plansDir = join47(homedir37(), ".letta", "plans");
|
|
142522
142590
|
handlePlanKeepPlanning(`You must write your plan to a plan file before exiting plan mode.
|
|
142523
142591
|
` + (planFilePath ? `Plan file path: ${planFilePath}
|
|
142524
142592
|
` : "") + `Use a write tool to create your plan in ${plansDir}, then use ExitPlanMode to present the plan to the user.`);
|
|
@@ -142750,14 +142818,6 @@ If using apply_patch, use this exact relative patch path: ${applyPatchRelativePa
|
|
|
142750
142818
|
return estimatedLiveHeight < resumeThreshold;
|
|
142751
142819
|
});
|
|
142752
142820
|
}, [estimatedLiveHeight, terminalRows]);
|
|
142753
|
-
import_react103.useEffect(() => {
|
|
142754
|
-
if (loadingState === "ready" && agentProvenance?.isNew && agentId && !startupAutoInitConsumedRef.current) {
|
|
142755
|
-
startupAutoInitConsumedRef.current = true;
|
|
142756
|
-
if (settingsManager.isMemfsEnabled(agentId)) {
|
|
142757
|
-
autoInitPendingAgentIdsRef.current.add(agentId);
|
|
142758
|
-
}
|
|
142759
|
-
}
|
|
142760
|
-
}, [loadingState, agentProvenance, agentId]);
|
|
142761
142821
|
import_react103.useEffect(() => {
|
|
142762
142822
|
if (loadingState === "ready" && !welcomeCommittedRef.current && messageHistory.length === 0) {
|
|
142763
142823
|
if (!continueSession && !agentProvenance) {
|
|
@@ -143750,6 +143810,7 @@ var init_App2 = __esm(async () => {
|
|
|
143750
143810
|
init_diff2();
|
|
143751
143811
|
init_errorContext();
|
|
143752
143812
|
init_errorFormatter();
|
|
143813
|
+
init_initCommand();
|
|
143753
143814
|
init_messageQueueBridge();
|
|
143754
143815
|
init_pasteRegistry();
|
|
143755
143816
|
init_planName();
|
|
@@ -143827,7 +143888,6 @@ var init_App2 = __esm(async () => {
|
|
|
143827
143888
|
init_accumulator(),
|
|
143828
143889
|
init_approvalClassification(),
|
|
143829
143890
|
init_formatArgsDisplay(),
|
|
143830
|
-
init_initCommand(),
|
|
143831
143891
|
init_memoryReminder(),
|
|
143832
143892
|
init_memorySubagentCompletion(),
|
|
143833
143893
|
init_reflectionTranscript(),
|
|
@@ -143926,11 +143986,11 @@ __export(exports_terminalKeybindingInstaller2, {
|
|
|
143926
143986
|
import {
|
|
143927
143987
|
copyFileSync as copyFileSync2,
|
|
143928
143988
|
existsSync as existsSync38,
|
|
143929
|
-
mkdirSync as
|
|
143930
|
-
readFileSync as
|
|
143931
|
-
writeFileSync as
|
|
143989
|
+
mkdirSync as mkdirSync25,
|
|
143990
|
+
readFileSync as readFileSync21,
|
|
143991
|
+
writeFileSync as writeFileSync20
|
|
143932
143992
|
} from "node:fs";
|
|
143933
|
-
import { homedir as
|
|
143993
|
+
import { homedir as homedir38, platform as platform6 } from "node:os";
|
|
143934
143994
|
import { dirname as dirname19, join as join48 } from "node:path";
|
|
143935
143995
|
function detectTerminalType2() {
|
|
143936
143996
|
if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_CHANNEL) {
|
|
@@ -143963,7 +144023,7 @@ function getKeybindingsPath2(terminal) {
|
|
|
143963
144023
|
}[terminal];
|
|
143964
144024
|
const os8 = platform6();
|
|
143965
144025
|
if (os8 === "darwin") {
|
|
143966
|
-
return join48(
|
|
144026
|
+
return join48(homedir38(), "Library", "Application Support", appName, "User", "keybindings.json");
|
|
143967
144027
|
}
|
|
143968
144028
|
if (os8 === "win32") {
|
|
143969
144029
|
const appData = process.env.APPDATA;
|
|
@@ -143972,7 +144032,7 @@ function getKeybindingsPath2(terminal) {
|
|
|
143972
144032
|
return join48(appData, appName, "User", "keybindings.json");
|
|
143973
144033
|
}
|
|
143974
144034
|
if (os8 === "linux") {
|
|
143975
|
-
return join48(
|
|
144035
|
+
return join48(homedir38(), ".config", appName, "User", "keybindings.json");
|
|
143976
144036
|
}
|
|
143977
144037
|
return null;
|
|
143978
144038
|
}
|
|
@@ -143997,7 +144057,7 @@ function keybindingExists2(keybindingsPath) {
|
|
|
143997
144057
|
if (!existsSync38(keybindingsPath))
|
|
143998
144058
|
return false;
|
|
143999
144059
|
try {
|
|
144000
|
-
const content =
|
|
144060
|
+
const content = readFileSync21(keybindingsPath, { encoding: "utf-8" });
|
|
144001
144061
|
const keybindings = parseKeybindings2(content);
|
|
144002
144062
|
if (!keybindings)
|
|
144003
144063
|
return false;
|
|
@@ -144024,13 +144084,13 @@ function installKeybinding2(keybindingsPath) {
|
|
|
144024
144084
|
}
|
|
144025
144085
|
const parentDir = dirname19(keybindingsPath);
|
|
144026
144086
|
if (!existsSync38(parentDir)) {
|
|
144027
|
-
|
|
144087
|
+
mkdirSync25(parentDir, { recursive: true });
|
|
144028
144088
|
}
|
|
144029
144089
|
let keybindings = [];
|
|
144030
144090
|
let backupPath = null;
|
|
144031
144091
|
if (existsSync38(keybindingsPath)) {
|
|
144032
144092
|
backupPath = createBackup2(keybindingsPath);
|
|
144033
|
-
const content =
|
|
144093
|
+
const content = readFileSync21(keybindingsPath, { encoding: "utf-8" });
|
|
144034
144094
|
const parsed = parseKeybindings2(content);
|
|
144035
144095
|
if (parsed === null) {
|
|
144036
144096
|
return {
|
|
@@ -144043,7 +144103,7 @@ function installKeybinding2(keybindingsPath) {
|
|
|
144043
144103
|
keybindings.push(SHIFT_ENTER_KEYBINDING2);
|
|
144044
144104
|
const newContent = `${JSON.stringify(keybindings, null, 2)}
|
|
144045
144105
|
`;
|
|
144046
|
-
|
|
144106
|
+
writeFileSync20(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
144047
144107
|
return {
|
|
144048
144108
|
success: true,
|
|
144049
144109
|
backupPath: backupPath ?? undefined
|
|
@@ -144061,7 +144121,7 @@ function removeKeybinding2(keybindingsPath) {
|
|
|
144061
144121
|
if (!existsSync38(keybindingsPath)) {
|
|
144062
144122
|
return { success: true };
|
|
144063
144123
|
}
|
|
144064
|
-
const content =
|
|
144124
|
+
const content = readFileSync21(keybindingsPath, { encoding: "utf-8" });
|
|
144065
144125
|
const keybindings = parseKeybindings2(content);
|
|
144066
144126
|
if (!keybindings) {
|
|
144067
144127
|
return {
|
|
@@ -144072,7 +144132,7 @@ function removeKeybinding2(keybindingsPath) {
|
|
|
144072
144132
|
const filtered = keybindings.filter((kb) => !(kb.key?.toLowerCase() === "shift+enter" && kb.command === "workbench.action.terminal.sendSequence" && kb.when?.includes("terminalFocus")));
|
|
144073
144133
|
const newContent = `${JSON.stringify(filtered, null, 2)}
|
|
144074
144134
|
`;
|
|
144075
|
-
|
|
144135
|
+
writeFileSync20(keybindingsPath, newContent, { encoding: "utf-8" });
|
|
144076
144136
|
return { success: true };
|
|
144077
144137
|
} catch (error) {
|
|
144078
144138
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -144129,16 +144189,16 @@ function getWezTermConfigPath2() {
|
|
|
144129
144189
|
if (existsSync38(xdgPath))
|
|
144130
144190
|
return xdgPath;
|
|
144131
144191
|
}
|
|
144132
|
-
const configPath = join48(
|
|
144192
|
+
const configPath = join48(homedir38(), ".config", "wezterm", "wezterm.lua");
|
|
144133
144193
|
if (existsSync38(configPath))
|
|
144134
144194
|
return configPath;
|
|
144135
|
-
return join48(
|
|
144195
|
+
return join48(homedir38(), ".wezterm.lua");
|
|
144136
144196
|
}
|
|
144137
144197
|
function wezTermDeleteFixExists2(configPath) {
|
|
144138
144198
|
if (!existsSync38(configPath))
|
|
144139
144199
|
return false;
|
|
144140
144200
|
try {
|
|
144141
|
-
const content =
|
|
144201
|
+
const content = readFileSync21(configPath, { encoding: "utf-8" });
|
|
144142
144202
|
return content.includes("Letta Code: Fix Delete key") || content.includes("key = 'Delete'") && content.includes("SendString") && content.includes("\\x1b[3~");
|
|
144143
144203
|
} catch {
|
|
144144
144204
|
return false;
|
|
@@ -144155,7 +144215,7 @@ function installWezTermDeleteFix2() {
|
|
|
144155
144215
|
if (existsSync38(configPath)) {
|
|
144156
144216
|
backupPath = `${configPath}.letta-backup`;
|
|
144157
144217
|
copyFileSync2(configPath, backupPath);
|
|
144158
|
-
content =
|
|
144218
|
+
content = readFileSync21(configPath, { encoding: "utf-8" });
|
|
144159
144219
|
}
|
|
144160
144220
|
if (content.includes("return {") && !content.includes("local config")) {
|
|
144161
144221
|
content = content.replace(/return\s*\{/, "local config = {");
|
|
@@ -144183,9 +144243,9 @@ ${WEZTERM_DELETE_FIX2}
|
|
|
144183
144243
|
}
|
|
144184
144244
|
const parentDir = dirname19(configPath);
|
|
144185
144245
|
if (!existsSync38(parentDir)) {
|
|
144186
|
-
|
|
144246
|
+
mkdirSync25(parentDir, { recursive: true });
|
|
144187
144247
|
}
|
|
144188
|
-
|
|
144248
|
+
writeFileSync20(configPath, content, { encoding: "utf-8" });
|
|
144189
144249
|
return {
|
|
144190
144250
|
success: true,
|
|
144191
144251
|
backupPath: backupPath ?? undefined
|
|
@@ -144230,10 +144290,10 @@ __export(exports_settings2, {
|
|
|
144230
144290
|
loadProjectSettings: () => loadProjectSettings2,
|
|
144231
144291
|
getSetting: () => getSetting2
|
|
144232
144292
|
});
|
|
144233
|
-
import { homedir as
|
|
144293
|
+
import { homedir as homedir39 } from "node:os";
|
|
144234
144294
|
import { join as join49 } from "node:path";
|
|
144235
144295
|
function getSettingsPath2() {
|
|
144236
|
-
return join49(
|
|
144296
|
+
return join49(homedir39(), ".letta", "settings.json");
|
|
144237
144297
|
}
|
|
144238
144298
|
async function loadSettings2() {
|
|
144239
144299
|
const settingsPath = getSettingsPath2();
|
|
@@ -144520,7 +144580,8 @@ var init_defaults2 = __esm(async () => {
|
|
|
144520
144580
|
var exports_create2 = {};
|
|
144521
144581
|
__export(exports_create2, {
|
|
144522
144582
|
createAgentWithBaseToolsRecovery: () => createAgentWithBaseToolsRecovery2,
|
|
144523
|
-
createAgent: () => createAgent2
|
|
144583
|
+
createAgent: () => createAgent2,
|
|
144584
|
+
addBaseToolsToServer: () => addBaseToolsToServer2
|
|
144524
144585
|
});
|
|
144525
144586
|
function isToolsNotFoundError2(err) {
|
|
144526
144587
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -144755,10 +144816,10 @@ __export(exports_import2, {
|
|
|
144755
144816
|
});
|
|
144756
144817
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
144757
144818
|
import { chmod as chmod2, mkdir as mkdir8, readFile as readFile14, writeFile as writeFile9 } from "node:fs/promises";
|
|
144758
|
-
import { dirname as dirname20, resolve as
|
|
144819
|
+
import { dirname as dirname20, resolve as resolve32 } from "node:path";
|
|
144759
144820
|
async function importAgentFromFile2(options) {
|
|
144760
144821
|
const client = await getClient();
|
|
144761
|
-
const resolvedPath =
|
|
144822
|
+
const resolvedPath = resolve32(options.filePath);
|
|
144762
144823
|
const file = createReadStream2(resolvedPath);
|
|
144763
144824
|
const importResponse = await client.agents.importFile({
|
|
144764
144825
|
file,
|
|
@@ -144793,7 +144854,7 @@ async function extractSkillsFromAf2(afPath, destDir) {
|
|
|
144793
144854
|
return [];
|
|
144794
144855
|
}
|
|
144795
144856
|
for (const skill2 of afData.skills) {
|
|
144796
|
-
const skillDir =
|
|
144857
|
+
const skillDir = resolve32(destDir, skill2.name);
|
|
144797
144858
|
await mkdir8(skillDir, { recursive: true });
|
|
144798
144859
|
if (skill2.files) {
|
|
144799
144860
|
await writeSkillFiles2(skillDir, skill2.files);
|
|
@@ -144813,7 +144874,7 @@ async function writeSkillFiles2(skillDir, files) {
|
|
|
144813
144874
|
}
|
|
144814
144875
|
}
|
|
144815
144876
|
async function writeSkillFile2(skillDir, filePath, content) {
|
|
144816
|
-
const fullPath =
|
|
144877
|
+
const fullPath = resolve32(skillDir, filePath);
|
|
144817
144878
|
await mkdir8(dirname20(fullPath), { recursive: true });
|
|
144818
144879
|
await writeFile9(fullPath, content, "utf-8");
|
|
144819
144880
|
const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
|
|
@@ -144923,23 +144984,23 @@ __export(exports_memoryFilesystem2, {
|
|
|
144923
144984
|
MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR2,
|
|
144924
144985
|
MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR2
|
|
144925
144986
|
});
|
|
144926
|
-
import { existsSync as existsSync39, mkdirSync as
|
|
144927
|
-
import { homedir as
|
|
144987
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync26 } from "node:fs";
|
|
144988
|
+
import { homedir as homedir40 } from "node:os";
|
|
144928
144989
|
import { join as join50 } from "node:path";
|
|
144929
|
-
function getMemoryFilesystemRoot2(agentId, homeDir =
|
|
144990
|
+
function getMemoryFilesystemRoot2(agentId, homeDir = homedir40()) {
|
|
144930
144991
|
return join50(homeDir, MEMORY_FS_ROOT2, MEMORY_FS_AGENTS_DIR2, agentId, MEMORY_FS_MEMORY_DIR2);
|
|
144931
144992
|
}
|
|
144932
|
-
function getMemorySystemDir2(agentId, homeDir =
|
|
144993
|
+
function getMemorySystemDir2(agentId, homeDir = homedir40()) {
|
|
144933
144994
|
return join50(getMemoryFilesystemRoot2(agentId, homeDir), MEMORY_SYSTEM_DIR2);
|
|
144934
144995
|
}
|
|
144935
|
-
function ensureMemoryFilesystemDirs2(agentId, homeDir =
|
|
144996
|
+
function ensureMemoryFilesystemDirs2(agentId, homeDir = homedir40()) {
|
|
144936
144997
|
const root = getMemoryFilesystemRoot2(agentId, homeDir);
|
|
144937
144998
|
const systemDir = getMemorySystemDir2(agentId, homeDir);
|
|
144938
144999
|
if (!existsSync39(root)) {
|
|
144939
|
-
|
|
145000
|
+
mkdirSync26(root, { recursive: true });
|
|
144940
145001
|
}
|
|
144941
145002
|
if (!existsSync39(systemDir)) {
|
|
144942
|
-
|
|
145003
|
+
mkdirSync26(systemDir, { recursive: true });
|
|
144943
145004
|
}
|
|
144944
145005
|
}
|
|
144945
145006
|
function labelFromRelativePath2(relativePath) {
|
|
@@ -149377,11 +149438,11 @@ async function runListenSubcommand(argv) {
|
|
|
149377
149438
|
connectionName = hostname3();
|
|
149378
149439
|
settingsManager.setListenerEnvName(connectionName);
|
|
149379
149440
|
} else {
|
|
149380
|
-
connectionName = await new Promise((
|
|
149441
|
+
connectionName = await new Promise((resolve24) => {
|
|
149381
149442
|
const { unmount } = render_default(/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(PromptEnvName, {
|
|
149382
149443
|
onSubmit: (name) => {
|
|
149383
149444
|
unmount();
|
|
149384
|
-
|
|
149445
|
+
resolve24(name);
|
|
149385
149446
|
}
|
|
149386
149447
|
}, undefined, false, undefined, this));
|
|
149387
149448
|
});
|
|
@@ -149439,7 +149500,11 @@ async function runListenSubcommand(argv) {
|
|
|
149439
149500
|
sessionLog.log(`Re-registered: connectionId=${result.connectionId}`);
|
|
149440
149501
|
return result;
|
|
149441
149502
|
};
|
|
149503
|
+
const shouldLogWsEvents = debugMode || process.env.LETTA_LOG_WS_EVENTS === "1";
|
|
149442
149504
|
const wsEventLogger = (direction, label, event) => {
|
|
149505
|
+
if (!shouldLogWsEvents) {
|
|
149506
|
+
return;
|
|
149507
|
+
}
|
|
149443
149508
|
sessionLog.wsEvent(direction, label, event);
|
|
149444
149509
|
if (debugMode) {
|
|
149445
149510
|
const arrow = direction === "send" ? "→ send" : "← recv";
|
|
@@ -149455,7 +149520,7 @@ async function runListenSubcommand(argv) {
|
|
|
149455
149520
|
wsUrl: url,
|
|
149456
149521
|
deviceId,
|
|
149457
149522
|
connectionName,
|
|
149458
|
-
onWsEvent: wsEventLogger,
|
|
149523
|
+
onWsEvent: shouldLogWsEvents ? wsEventLogger : undefined,
|
|
149459
149524
|
onStatusChange: (status) => {
|
|
149460
149525
|
sessionLog.log(`status: ${status}`);
|
|
149461
149526
|
console.log(`[${formatTimestamp3()}] status: ${status}`);
|
|
@@ -149514,7 +149579,7 @@ async function runListenSubcommand(argv) {
|
|
|
149514
149579
|
wsUrl: url,
|
|
149515
149580
|
deviceId,
|
|
149516
149581
|
connectionName,
|
|
149517
|
-
onWsEvent: wsEventLogger,
|
|
149582
|
+
onWsEvent: shouldLogWsEvents ? wsEventLogger : undefined,
|
|
149518
149583
|
onStatusChange: (status) => {
|
|
149519
149584
|
sessionLog.log(`status: ${status}`);
|
|
149520
149585
|
clearRetryStatusCallback?.();
|
|
@@ -149576,10 +149641,10 @@ async function runListenSubcommand(argv) {
|
|
|
149576
149641
|
|
|
149577
149642
|
// src/cli/subcommands/memfs.ts
|
|
149578
149643
|
await init_memoryGit();
|
|
149579
|
-
import { cpSync, existsSync as
|
|
149644
|
+
import { cpSync, existsSync as existsSync21, mkdirSync as mkdirSync15, rmSync as rmSync3, statSync as statSync8 } from "node:fs";
|
|
149580
149645
|
import { readdir as readdir6 } from "node:fs/promises";
|
|
149581
149646
|
import { homedir as homedir23 } from "node:os";
|
|
149582
|
-
import { join as
|
|
149647
|
+
import { join as join27 } from "node:path";
|
|
149583
149648
|
import { parseArgs as parseArgs7 } from "node:util";
|
|
149584
149649
|
function printUsage4() {
|
|
149585
149650
|
console.log(`
|
|
@@ -149624,10 +149689,10 @@ function parseMemfsArgs(argv) {
|
|
|
149624
149689
|
});
|
|
149625
149690
|
}
|
|
149626
149691
|
function getMemoryRoot(agentId) {
|
|
149627
|
-
return
|
|
149692
|
+
return join27(homedir23(), ".letta", "agents", agentId, "memory");
|
|
149628
149693
|
}
|
|
149629
149694
|
function getAgentRoot(agentId) {
|
|
149630
|
-
return
|
|
149695
|
+
return join27(homedir23(), ".letta", "agents", agentId);
|
|
149631
149696
|
}
|
|
149632
149697
|
function formatBackupTimestamp(date = new Date) {
|
|
149633
149698
|
const pad = (value) => String(value).padStart(2, "0");
|
|
@@ -149641,7 +149706,7 @@ function formatBackupTimestamp(date = new Date) {
|
|
|
149641
149706
|
}
|
|
149642
149707
|
async function listBackups(agentId) {
|
|
149643
149708
|
const agentRoot = getAgentRoot(agentId);
|
|
149644
|
-
if (!
|
|
149709
|
+
if (!existsSync21(agentRoot)) {
|
|
149645
149710
|
return [];
|
|
149646
149711
|
}
|
|
149647
149712
|
const entries = await readdir6(agentRoot, { withFileTypes: true });
|
|
@@ -149651,7 +149716,7 @@ async function listBackups(agentId) {
|
|
|
149651
149716
|
continue;
|
|
149652
149717
|
if (!entry.name.startsWith("memory-backup-"))
|
|
149653
149718
|
continue;
|
|
149654
|
-
const path23 =
|
|
149719
|
+
const path23 = join27(agentRoot, entry.name);
|
|
149655
149720
|
let createdAt = null;
|
|
149656
149721
|
try {
|
|
149657
149722
|
const stat6 = statSync8(path23);
|
|
@@ -149668,7 +149733,7 @@ function resolveBackupPath(agentId, from) {
|
|
|
149668
149733
|
if (from.startsWith("/") || /^[A-Za-z]:[/\\]/.test(from)) {
|
|
149669
149734
|
return from;
|
|
149670
149735
|
}
|
|
149671
|
-
return
|
|
149736
|
+
return join27(getAgentRoot(agentId), from);
|
|
149672
149737
|
}
|
|
149673
149738
|
async function runMemfsSubcommand(argv) {
|
|
149674
149739
|
let parsed;
|
|
@@ -149728,14 +149793,14 @@ async function runMemfsSubcommand(argv) {
|
|
|
149728
149793
|
}
|
|
149729
149794
|
if (action === "backup") {
|
|
149730
149795
|
const root = getMemoryRoot(agentId);
|
|
149731
|
-
if (!
|
|
149796
|
+
if (!existsSync21(root)) {
|
|
149732
149797
|
console.error(`Memory directory not found for agent ${agentId}.`);
|
|
149733
149798
|
return 1;
|
|
149734
149799
|
}
|
|
149735
149800
|
const agentRoot = getAgentRoot(agentId);
|
|
149736
149801
|
const backupName = `memory-backup-${formatBackupTimestamp()}`;
|
|
149737
|
-
const backupPath =
|
|
149738
|
-
if (
|
|
149802
|
+
const backupPath = join27(agentRoot, backupName);
|
|
149803
|
+
if (existsSync21(backupPath)) {
|
|
149739
149804
|
console.error(`Backup already exists at ${backupPath}`);
|
|
149740
149805
|
return 1;
|
|
149741
149806
|
}
|
|
@@ -149759,7 +149824,7 @@ async function runMemfsSubcommand(argv) {
|
|
|
149759
149824
|
return 1;
|
|
149760
149825
|
}
|
|
149761
149826
|
const backupPath = resolveBackupPath(agentId, from);
|
|
149762
|
-
if (!
|
|
149827
|
+
if (!existsSync21(backupPath)) {
|
|
149763
149828
|
console.error(`Backup not found: ${backupPath}`);
|
|
149764
149829
|
return 1;
|
|
149765
149830
|
}
|
|
@@ -149781,11 +149846,11 @@ async function runMemfsSubcommand(argv) {
|
|
|
149781
149846
|
return 1;
|
|
149782
149847
|
}
|
|
149783
149848
|
const root = getMemoryRoot(agentId);
|
|
149784
|
-
if (!
|
|
149849
|
+
if (!existsSync21(root)) {
|
|
149785
149850
|
console.error(`Memory directory not found for agent ${agentId}.`);
|
|
149786
149851
|
return 1;
|
|
149787
149852
|
}
|
|
149788
|
-
if (
|
|
149853
|
+
if (existsSync21(out)) {
|
|
149789
149854
|
const stat6 = statSync8(out);
|
|
149790
149855
|
if (stat6.isDirectory()) {
|
|
149791
149856
|
const contents = await readdir6(out);
|
|
@@ -149816,7 +149881,7 @@ async function runMemfsSubcommand(argv) {
|
|
|
149816
149881
|
// src/cli/subcommands/messages.ts
|
|
149817
149882
|
await init_client2();
|
|
149818
149883
|
import { writeFile as writeFile6 } from "node:fs/promises";
|
|
149819
|
-
import { resolve as
|
|
149884
|
+
import { resolve as resolve24 } from "node:path";
|
|
149820
149885
|
import { parseArgs as parseArgs8 } from "node:util";
|
|
149821
149886
|
function printUsage5() {
|
|
149822
149887
|
console.log(`
|
|
@@ -150120,7 +150185,7 @@ async function runMessagesSubcommand(argv) {
|
|
|
150120
150185
|
|
|
150121
150186
|
`).trim();
|
|
150122
150187
|
if (outputPathRaw && typeof outputPathRaw === "string") {
|
|
150123
|
-
const outputPath =
|
|
150188
|
+
const outputPath = resolve24(process.cwd(), outputPathRaw);
|
|
150124
150189
|
await writeFile6(outputPath, `${transcript}
|
|
150125
150190
|
`, "utf-8");
|
|
150126
150191
|
console.log(JSON.stringify({
|
|
@@ -150180,7 +150245,7 @@ init_memoryScope();
|
|
|
150180
150245
|
init_readOnlyShell();
|
|
150181
150246
|
init_shell_command_normalization();
|
|
150182
150247
|
import { homedir as homedir24 } from "node:os";
|
|
150183
|
-
import { isAbsolute as isAbsolute17, join as
|
|
150248
|
+
import { isAbsolute as isAbsolute17, join as join28, relative as relative12 } from "node:path";
|
|
150184
150249
|
var MODE_KEY2 = Symbol.for("@letta/permissionMode");
|
|
150185
150250
|
var PLAN_FILE_KEY2 = Symbol.for("@letta/planFilePath");
|
|
150186
150251
|
var MODE_BEFORE_PLAN_KEY2 = Symbol.for("@letta/permissionModeBeforePlan");
|
|
@@ -150346,6 +150411,7 @@ class PermissionModeManager2 {
|
|
|
150346
150411
|
"Edit",
|
|
150347
150412
|
"MultiEdit",
|
|
150348
150413
|
"NotebookEdit",
|
|
150414
|
+
"memory",
|
|
150349
150415
|
"apply_patch",
|
|
150350
150416
|
"ApplyPatch",
|
|
150351
150417
|
"memory_apply_patch",
|
|
@@ -150411,7 +150477,7 @@ class PermissionModeManager2 {
|
|
|
150411
150477
|
return "allow";
|
|
150412
150478
|
}
|
|
150413
150479
|
if (writeTools.includes(toolName)) {
|
|
150414
|
-
const plansDir =
|
|
150480
|
+
const plansDir = join28(homedir24(), ".letta", "plans");
|
|
150415
150481
|
const targetPath = toolArgs?.file_path || toolArgs?.path;
|
|
150416
150482
|
let candidatePaths = [];
|
|
150417
150483
|
if ((toolName === "ApplyPatch" || toolName === "apply_patch" || toolName === "memory_apply_patch") && toolArgs?.input) {
|
|
@@ -150462,7 +150528,7 @@ class PermissionModeManager2 {
|
|
|
150462
150528
|
}
|
|
150463
150529
|
const planWritePath = extractPlanFileWritePathFromShellCommand2(command);
|
|
150464
150530
|
if (planWritePath) {
|
|
150465
|
-
const plansDir =
|
|
150531
|
+
const plansDir = join28(homedir24(), ".letta", "plans");
|
|
150466
150532
|
const resolvedPath = resolvePlanTargetPath2(planWritePath, workingDirectory);
|
|
150467
150533
|
if (resolvedPath && isPathInPlansDir2(resolvedPath, plansDir)) {
|
|
150468
150534
|
return "allow";
|
|
@@ -150582,7 +150648,7 @@ await __promiseAll([
|
|
|
150582
150648
|
]);
|
|
150583
150649
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
150584
150650
|
import { homedir as homedir25 } from "node:os";
|
|
150585
|
-
import { join as
|
|
150651
|
+
import { join as join29, resolve as resolve25 } from "node:path";
|
|
150586
150652
|
var DEFAULT_SETTINGS3 = {
|
|
150587
150653
|
lastAgent: null,
|
|
150588
150654
|
tokenStreaming: false,
|
|
@@ -150969,7 +151035,7 @@ class SettingsManager2 {
|
|
|
150969
151035
|
return;
|
|
150970
151036
|
const settingsPath = this.getSettingsPath();
|
|
150971
151037
|
const home = process.env.HOME || homedir25();
|
|
150972
|
-
const dirPath =
|
|
151038
|
+
const dirPath = join29(home, ".letta");
|
|
150973
151039
|
try {
|
|
150974
151040
|
if (!exists(dirPath)) {
|
|
150975
151041
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -151008,7 +151074,7 @@ class SettingsManager2 {
|
|
|
151008
151074
|
if (!settings)
|
|
151009
151075
|
return;
|
|
151010
151076
|
const settingsPath = this.getProjectSettingsPath(workingDirectory);
|
|
151011
|
-
const dirPath =
|
|
151077
|
+
const dirPath = join29(workingDirectory, ".letta");
|
|
151012
151078
|
try {
|
|
151013
151079
|
let existingSettings = {};
|
|
151014
151080
|
if (exists(settingsPath)) {
|
|
@@ -151030,16 +151096,16 @@ class SettingsManager2 {
|
|
|
151030
151096
|
}
|
|
151031
151097
|
getSettingsPath() {
|
|
151032
151098
|
const home = process.env.HOME || homedir25();
|
|
151033
|
-
return
|
|
151099
|
+
return join29(home, ".letta", "settings.json");
|
|
151034
151100
|
}
|
|
151035
151101
|
getProjectSettingsPath(workingDirectory) {
|
|
151036
|
-
return
|
|
151102
|
+
return join29(workingDirectory, ".letta", "settings.json");
|
|
151037
151103
|
}
|
|
151038
151104
|
isProjectSettingsPathCollidingWithGlobal(workingDirectory) {
|
|
151039
|
-
return
|
|
151105
|
+
return resolve25(this.getProjectSettingsPath(workingDirectory)) === resolve25(this.getSettingsPath());
|
|
151040
151106
|
}
|
|
151041
151107
|
getLocalProjectSettingsPath(workingDirectory) {
|
|
151042
|
-
return
|
|
151108
|
+
return join29(workingDirectory, ".letta", "settings.local.json");
|
|
151043
151109
|
}
|
|
151044
151110
|
async loadLocalProjectSettings(workingDirectory = process.cwd()) {
|
|
151045
151111
|
const cached = this.localProjectSettings.get(workingDirectory);
|
|
@@ -151100,7 +151166,7 @@ class SettingsManager2 {
|
|
|
151100
151166
|
if (!settings)
|
|
151101
151167
|
return;
|
|
151102
151168
|
const settingsPath = this.getLocalProjectSettingsPath(workingDirectory);
|
|
151103
|
-
const dirPath =
|
|
151169
|
+
const dirPath = join29(workingDirectory, ".letta");
|
|
151104
151170
|
try {
|
|
151105
151171
|
if (!exists(dirPath)) {
|
|
151106
151172
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -151454,7 +151520,7 @@ class SettingsManager2 {
|
|
|
151454
151520
|
this.upsertAgentSettings(agentId, { systemPromptPreset: "" });
|
|
151455
151521
|
}
|
|
151456
151522
|
hasLocalLettaDir(workingDirectory = process.cwd()) {
|
|
151457
|
-
const dirPath =
|
|
151523
|
+
const dirPath = join29(workingDirectory, ".letta");
|
|
151458
151524
|
return exists(dirPath);
|
|
151459
151525
|
}
|
|
151460
151526
|
storeOAuthState(state, codeVerifier, redirectUri, provider) {
|
|
@@ -151998,8 +152064,8 @@ function acquireSwitchLock2() {
|
|
|
151998
152064
|
const lock = getSwitchLock2();
|
|
151999
152065
|
lock.refCount++;
|
|
152000
152066
|
if (lock.refCount === 1) {
|
|
152001
|
-
lock.promise = new Promise((
|
|
152002
|
-
lock.resolve =
|
|
152067
|
+
lock.promise = new Promise((resolve26) => {
|
|
152068
|
+
lock.resolve = resolve26;
|
|
152003
152069
|
});
|
|
152004
152070
|
}
|
|
152005
152071
|
}
|
|
@@ -152444,6 +152510,8 @@ async function main() {
|
|
|
152444
152510
|
await settingsManager2.initialize();
|
|
152445
152511
|
const settings = await settingsManager2.getSettingsWithSecureTokens();
|
|
152446
152512
|
markMilestone2("SETTINGS_LOADED");
|
|
152513
|
+
const { bootstrapBaseToolsIfNeeded: bootstrapBaseToolsIfNeeded2 } = await init_bootstrap_tools().then(() => exports_bootstrap_tools);
|
|
152514
|
+
await bootstrapBaseToolsIfNeeded2();
|
|
152447
152515
|
const subcommandResult = await runSubcommand(process.argv.slice(2));
|
|
152448
152516
|
if (subcommandResult !== null) {
|
|
152449
152517
|
process.exit(subcommandResult);
|
|
@@ -152484,7 +152552,7 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
152484
152552
|
printHelp();
|
|
152485
152553
|
const helpDelayMs = Number.parseInt(process.env.LETTA_TEST_HELP_EXIT_DELAY_MS ?? "", 10);
|
|
152486
152554
|
if (Number.isFinite(helpDelayMs) && helpDelayMs > 0) {
|
|
152487
|
-
await new Promise((
|
|
152555
|
+
await new Promise((resolve33) => setTimeout(resolve33, helpDelayMs));
|
|
152488
152556
|
}
|
|
152489
152557
|
process.exit(0);
|
|
152490
152558
|
}
|
|
@@ -152706,9 +152774,9 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
152706
152774
|
process.exit(1);
|
|
152707
152775
|
}
|
|
152708
152776
|
} else {
|
|
152709
|
-
const { resolve:
|
|
152777
|
+
const { resolve: resolve33 } = await import("path");
|
|
152710
152778
|
const { existsSync: existsSync40 } = await import("fs");
|
|
152711
|
-
const resolvedPath =
|
|
152779
|
+
const resolvedPath = resolve33(fromAfFile);
|
|
152712
152780
|
if (!existsSync40(resolvedPath)) {
|
|
152713
152781
|
console.error(`Error: AgentFile not found: ${resolvedPath}`);
|
|
152714
152782
|
process.exit(1);
|
|
@@ -153584,4 +153652,4 @@ Error during initialization: ${message}`);
|
|
|
153584
153652
|
}
|
|
153585
153653
|
main();
|
|
153586
153654
|
|
|
153587
|
-
//# debugId=
|
|
153655
|
+
//# debugId=EB5AD8CB3C0EDF1664756E2164756E21
|