@letta-ai/letta-code 0.19.4 → 0.19.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/letta.js +273 -46
  2. package/package.json +2 -2
package/letta.js CHANGED
@@ -3240,7 +3240,7 @@ var package_default;
3240
3240
  var init_package = __esm(() => {
3241
3241
  package_default = {
3242
3242
  name: "@letta-ai/letta-code",
3243
- version: "0.19.4",
3243
+ version: "0.19.5",
3244
3244
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
3245
3245
  type: "module",
3246
3246
  bin: {
@@ -3308,7 +3308,7 @@ var init_package = __esm(() => {
3308
3308
  fix: "bunx --bun @biomejs/biome@2.2.5 check --write src",
3309
3309
  typecheck: "tsc --noEmit",
3310
3310
  check: "bun run scripts/check.js",
3311
- dev: "LETTA_DEBUG=1 bun --loader:.md=text --loader:.mdx=text --loader:.txt=text run src/index.ts",
3311
+ dev: "LETTA_DEBUG=${LETTA_DEBUG:-1} bun --loader:.md=text --loader:.mdx=text --loader:.txt=text run src/index.ts",
3312
3312
  build: "node scripts/postinstall-patches.js && bun run build.js",
3313
3313
  "test:update-chain:manual": "bun run src/tests/update-chain-smoke.ts --mode manual",
3314
3314
  "test:update-chain:startup": "bun run src/tests/update-chain-smoke.ts --mode startup",
@@ -4858,7 +4858,7 @@ var init_memory_check_reminder = () => {};
4858
4858
  var memory_filesystem_default = `---
4859
4859
  label: memory_filesystem
4860
4860
  description: Filesystem view of memory blocks (system + user)
4861
- limit: 20000
4861
+ limit: 8000
4862
4862
  ---
4863
4863
 
4864
4864
  /memory/
@@ -44712,6 +44712,56 @@ var init_process_manager = __esm(() => {
44712
44712
  backgroundTasks = new Map;
44713
44713
  });
44714
44714
 
44715
+ // src/utils/directoryLimits.ts
44716
+ function parsePositiveIntEnv(value, fallback, min, max) {
44717
+ if (!value || value.trim() === "") {
44718
+ return fallback;
44719
+ }
44720
+ const parsed = Number.parseInt(value.trim(), 10);
44721
+ if (Number.isNaN(parsed)) {
44722
+ return fallback;
44723
+ }
44724
+ if (parsed < min || parsed > max) {
44725
+ return fallback;
44726
+ }
44727
+ return parsed;
44728
+ }
44729
+ function getDirectoryLimits(env3 = process.env) {
44730
+ return {
44731
+ memfsTreeMaxLines: parsePositiveIntEnv(env3[DIRECTORY_LIMIT_ENV.memfsTreeMaxLines], DIRECTORY_LIMIT_DEFAULTS.memfsTreeMaxLines, 2, 50000),
44732
+ memfsTreeMaxChars: parsePositiveIntEnv(env3[DIRECTORY_LIMIT_ENV.memfsTreeMaxChars], DIRECTORY_LIMIT_DEFAULTS.memfsTreeMaxChars, 128, 5000000),
44733
+ memfsTreeMaxChildrenPerDir: parsePositiveIntEnv(env3[DIRECTORY_LIMIT_ENV.memfsTreeMaxChildrenPerDir], DIRECTORY_LIMIT_DEFAULTS.memfsTreeMaxChildrenPerDir, 1, 5000),
44734
+ listDirMaxLimit: parsePositiveIntEnv(env3[DIRECTORY_LIMIT_ENV.listDirMaxLimit], DIRECTORY_LIMIT_DEFAULTS.listDirMaxLimit, 1, 1e4),
44735
+ listDirMaxDepth: parsePositiveIntEnv(env3[DIRECTORY_LIMIT_ENV.listDirMaxDepth], DIRECTORY_LIMIT_DEFAULTS.listDirMaxDepth, 1, 100),
44736
+ listDirMaxOffset: parsePositiveIntEnv(env3[DIRECTORY_LIMIT_ENV.listDirMaxOffset], DIRECTORY_LIMIT_DEFAULTS.listDirMaxOffset, 1, 1e6),
44737
+ listDirMaxCollectedEntries: parsePositiveIntEnv(env3[DIRECTORY_LIMIT_ENV.listDirMaxCollectedEntries], DIRECTORY_LIMIT_DEFAULTS.listDirMaxCollectedEntries, 10, 2000000),
44738
+ listDirMaxChildrenPerDir: parsePositiveIntEnv(env3[DIRECTORY_LIMIT_ENV.listDirMaxChildrenPerDir], DIRECTORY_LIMIT_DEFAULTS.listDirMaxChildrenPerDir, 1, 5000)
44739
+ };
44740
+ }
44741
+ var DIRECTORY_LIMIT_ENV, DIRECTORY_LIMIT_DEFAULTS;
44742
+ var init_directoryLimits = __esm(() => {
44743
+ DIRECTORY_LIMIT_ENV = {
44744
+ memfsTreeMaxLines: "LETTA_MEMFS_TREE_MAX_LINES",
44745
+ memfsTreeMaxChars: "LETTA_MEMFS_TREE_MAX_CHARS",
44746
+ memfsTreeMaxChildrenPerDir: "LETTA_MEMFS_TREE_MAX_CHILDREN_PER_DIR",
44747
+ listDirMaxLimit: "LETTA_LIST_DIR_MAX_LIMIT",
44748
+ listDirMaxDepth: "LETTA_LIST_DIR_MAX_DEPTH",
44749
+ listDirMaxOffset: "LETTA_LIST_DIR_MAX_OFFSET",
44750
+ listDirMaxCollectedEntries: "LETTA_LIST_DIR_MAX_COLLECTED_ENTRIES",
44751
+ listDirMaxChildrenPerDir: "LETTA_LIST_DIR_MAX_CHILDREN_PER_DIR"
44752
+ };
44753
+ DIRECTORY_LIMIT_DEFAULTS = {
44754
+ memfsTreeMaxLines: 500,
44755
+ memfsTreeMaxChars: 20000,
44756
+ memfsTreeMaxChildrenPerDir: 50,
44757
+ listDirMaxLimit: 200,
44758
+ listDirMaxDepth: 5,
44759
+ listDirMaxOffset: 1e4,
44760
+ listDirMaxCollectedEntries: 12000,
44761
+ listDirMaxChildrenPerDir: 50
44762
+ };
44763
+ });
44764
+
44715
44765
  // src/agent/memoryGit.ts
44716
44766
  var exports_memoryGit = {};
44717
44767
  __export(exports_memoryGit, {
@@ -45563,6 +45613,9 @@ __export(exports_memoryFilesystem, {
45563
45613
  ensureMemoryFilesystemDirs: () => ensureMemoryFilesystemDirs,
45564
45614
  enableMemfsIfCloud: () => enableMemfsIfCloud,
45565
45615
  applyMemfsFlags: () => applyMemfsFlags,
45616
+ MEMORY_TREE_MAX_LINES: () => MEMORY_TREE_MAX_LINES,
45617
+ MEMORY_TREE_MAX_CHILDREN_PER_DIR: () => MEMORY_TREE_MAX_CHILDREN_PER_DIR,
45618
+ MEMORY_TREE_MAX_CHARS: () => MEMORY_TREE_MAX_CHARS,
45566
45619
  MEMORY_SYSTEM_DIR: () => MEMORY_SYSTEM_DIR,
45567
45620
  MEMORY_FS_ROOT: () => MEMORY_FS_ROOT,
45568
45621
  MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR,
@@ -45591,7 +45644,7 @@ function labelFromRelativePath(relativePath) {
45591
45644
  const normalized = relativePath.replace(/\\/g, "/");
45592
45645
  return normalized.replace(/\.md$/, "");
45593
45646
  }
45594
- function renderMemoryFilesystemTree(systemLabels, detachedLabels) {
45647
+ function renderMemoryFilesystemTree(systemLabels, detachedLabels, options = {}) {
45595
45648
  const makeNode = () => ({ children: new Map, isFile: false });
45596
45649
  const root = makeNode();
45597
45650
  const insertPath = (base2, label) => {
@@ -45626,20 +45679,75 @@ function renderMemoryFilesystemTree(systemLabels, detachedLabels) {
45626
45679
  return nameA.localeCompare(nameB);
45627
45680
  });
45628
45681
  };
45629
- const lines = ["/memory/"];
45682
+ const limits = getDirectoryLimits();
45683
+ const maxLines = Math.max(2, options.maxLines ?? limits.memfsTreeMaxLines);
45684
+ const maxChars = Math.max(128, options.maxChars ?? limits.memfsTreeMaxChars);
45685
+ const maxChildrenPerDir = Math.max(1, options.maxChildrenPerDir ?? limits.memfsTreeMaxChildrenPerDir);
45686
+ const rootLine = "/memory/";
45687
+ const lines = [rootLine];
45688
+ let totalChars = rootLine.length;
45689
+ const countTreeEntries = (node) => {
45690
+ let total = 0;
45691
+ for (const [, child] of node.children) {
45692
+ total += 1;
45693
+ if (child.children.size > 0) {
45694
+ total += countTreeEntries(child);
45695
+ }
45696
+ }
45697
+ return total;
45698
+ };
45699
+ const canAppendLine = (line) => {
45700
+ const nextLineCount = lines.length + 1;
45701
+ const nextCharCount = totalChars + 1 + line.length;
45702
+ return nextLineCount <= maxLines && nextCharCount <= maxChars;
45703
+ };
45630
45704
  const render2 = (node, prefix) => {
45631
45705
  const entries = sortedEntries(node);
45632
- entries.forEach(([name, child], index) => {
45633
- const isLast = index === entries.length - 1;
45706
+ const visibleEntries = entries.slice(0, maxChildrenPerDir);
45707
+ const omittedEntries = Math.max(0, entries.length - visibleEntries.length);
45708
+ const renderItems = visibleEntries.map(([name, child]) => ({
45709
+ kind: "entry",
45710
+ name,
45711
+ child
45712
+ }));
45713
+ if (omittedEntries > 0) {
45714
+ renderItems.push({ kind: "omitted", omittedCount: omittedEntries });
45715
+ }
45716
+ for (const [index, item] of renderItems.entries()) {
45717
+ const isLast = index === renderItems.length - 1;
45634
45718
  const branch = isLast ? "└──" : "├──";
45635
- lines.push(`${prefix}${branch} ${name}${child.isFile ? "" : "/"}`);
45636
- if (child.children.size > 0) {
45719
+ const line = item.kind === "entry" ? `${prefix}${branch} ${item.name}${item.child.isFile ? "" : "/"}` : `${prefix}${branch} … (${item.omittedCount.toLocaleString()} more entries)`;
45720
+ if (!canAppendLine(line)) {
45721
+ return false;
45722
+ }
45723
+ lines.push(line);
45724
+ totalChars += 1 + line.length;
45725
+ if (item.kind === "entry" && item.child.children.size > 0) {
45637
45726
  const nextPrefix = `${prefix}${isLast ? " " : "│ "}`;
45638
- render2(child, nextPrefix);
45727
+ if (!render2(item.child, nextPrefix)) {
45728
+ return false;
45729
+ }
45639
45730
  }
45640
- });
45731
+ }
45732
+ return true;
45641
45733
  };
45642
- render2(root, "");
45734
+ const totalEntries = countTreeEntries(root);
45735
+ const fullyRendered = render2(root, "");
45736
+ if (!fullyRendered) {
45737
+ while (lines.length > 1) {
45738
+ const shownEntries = Math.max(0, lines.length - 1);
45739
+ const omittedEntries = Math.max(1, totalEntries - shownEntries);
45740
+ const notice = `[Tree truncated: showing ${shownEntries.toLocaleString()} of ${totalEntries.toLocaleString()} entries. ${omittedEntries.toLocaleString()} omitted.]`;
45741
+ if (canAppendLine(notice)) {
45742
+ lines.push(notice);
45743
+ break;
45744
+ }
45745
+ const removed = lines.pop();
45746
+ if (removed) {
45747
+ totalChars -= 1 + removed.length;
45748
+ }
45749
+ }
45750
+ }
45643
45751
  return lines.join(`
45644
45752
  `);
45645
45753
  }
@@ -45721,8 +45829,13 @@ async function enableMemfsIfCloud(agentId) {
45721
45829
  console.warn(`Warning: Could not enable memfs for new agent: ${error instanceof Error ? error.message : String(error)}`);
45722
45830
  }
45723
45831
  }
45724
- var MEMORY_FS_ROOT = ".letta", MEMORY_FS_AGENTS_DIR = "agents", MEMORY_FS_MEMORY_DIR = "memory", MEMORY_SYSTEM_DIR = "system";
45725
- var init_memoryFilesystem = () => {};
45832
+ var MEMORY_FS_ROOT = ".letta", MEMORY_FS_AGENTS_DIR = "agents", MEMORY_FS_MEMORY_DIR = "memory", MEMORY_SYSTEM_DIR = "system", MEMORY_TREE_MAX_LINES, MEMORY_TREE_MAX_CHARS, MEMORY_TREE_MAX_CHILDREN_PER_DIR;
45833
+ var init_memoryFilesystem = __esm(() => {
45834
+ init_directoryLimits();
45835
+ MEMORY_TREE_MAX_LINES = DIRECTORY_LIMIT_DEFAULTS.memfsTreeMaxLines;
45836
+ MEMORY_TREE_MAX_CHARS = DIRECTORY_LIMIT_DEFAULTS.memfsTreeMaxChars;
45837
+ MEMORY_TREE_MAX_CHILDREN_PER_DIR = DIRECTORY_LIMIT_DEFAULTS.memfsTreeMaxChildrenPerDir;
45838
+ });
45726
45839
 
45727
45840
  // src/tools/impl/shellEnv.ts
45728
45841
  var exports_shellEnv = {};
@@ -47153,32 +47266,47 @@ import { promises as fs10 } from "node:fs";
47153
47266
  import * as path10 from "node:path";
47154
47267
  async function list_dir(args) {
47155
47268
  validateRequiredParams(args, ["dir_path"], "list_dir");
47156
- const { dir_path, offset = 1, limit: limit2 = 25, depth = 2 } = args;
47269
+ const limits = getDirectoryLimits();
47270
+ const {
47271
+ dir_path,
47272
+ offset = DEFAULT_OFFSET,
47273
+ limit: limit2 = DEFAULT_LIMIT2,
47274
+ depth = DEFAULT_DEPTH
47275
+ } = args;
47157
47276
  const userCwd = process.env.USER_CWD || process.cwd();
47158
47277
  const resolvedPath = path10.isAbsolute(dir_path) ? dir_path : path10.resolve(userCwd, dir_path);
47159
- if (offset < 1) {
47160
- throw new Error("offset must be a 1-indexed entry number");
47278
+ if (!Number.isInteger(offset) || offset < 1) {
47279
+ throw new Error("offset must be a positive integer (1-indexed)");
47161
47280
  }
47162
- if (limit2 < 1) {
47163
- throw new Error("limit must be greater than zero");
47281
+ if (offset > limits.listDirMaxOffset) {
47282
+ throw new Error(`offset must be less than or equal to ${limits.listDirMaxOffset.toLocaleString()}`);
47283
+ }
47284
+ if (!Number.isInteger(limit2) || limit2 < 1) {
47285
+ throw new Error("limit must be a positive integer");
47164
47286
  }
47165
- if (depth < 1) {
47166
- throw new Error("depth must be greater than zero");
47287
+ if (!Number.isInteger(depth) || depth < 1) {
47288
+ throw new Error("depth must be a positive integer");
47167
47289
  }
47168
- const entries = await listDirSlice(resolvedPath, offset, limit2, depth);
47290
+ const effectiveLimit = Math.min(limit2, limits.listDirMaxLimit);
47291
+ const effectiveDepth = Math.min(depth, limits.listDirMaxDepth);
47292
+ const entries = await listDirSlice(resolvedPath, offset, effectiveLimit, effectiveDepth, limits.listDirMaxCollectedEntries, limits.listDirMaxChildrenPerDir);
47169
47293
  const output = [`Absolute path: ${resolvedPath}`, ...entries];
47294
+ if (effectiveLimit !== limit2 || effectiveDepth !== depth) {
47295
+ output.push(`[Request capped: limit=${limit2}->${effectiveLimit}, depth=${depth}->${effectiveDepth}]`);
47296
+ }
47170
47297
  return { content: output.join(`
47171
47298
  `) };
47172
47299
  }
47173
- async function listDirSlice(dirPath, offset, limit2, maxDepth) {
47300
+ async function listDirSlice(dirPath, offset, limit2, maxDepth, maxCollectedEntries, maxChildrenPerDir) {
47174
47301
  const entries = [];
47175
- await collectEntries(dirPath, "", maxDepth, entries);
47302
+ const maxEntriesToCollect = Math.min(offset + limit2, maxCollectedEntries);
47303
+ const { hitCollectionCap, hitFolderTruncation } = await collectEntries(dirPath, "", maxDepth, entries, maxEntriesToCollect, maxChildrenPerDir);
47176
47304
  if (entries.length === 0) {
47177
47305
  return [];
47178
47306
  }
47179
47307
  const startIndex = offset - 1;
47180
47308
  if (startIndex >= entries.length) {
47181
- throw new Error("offset exceeds directory entry count");
47309
+ throw new Error(`offset exceeds available entries in current view (max offset: ${entries.length.toLocaleString()})`);
47182
47310
  }
47183
47311
  const remainingEntries = entries.length - startIndex;
47184
47312
  const cappedLimit = Math.min(limit2, remainingEntries);
@@ -47190,15 +47318,21 @@ async function listDirSlice(dirPath, offset, limit2, maxDepth) {
47190
47318
  formatted.push(formatEntryLine(entry));
47191
47319
  }
47192
47320
  if (endIndex < entries.length) {
47193
- formatted.push(`More than ${cappedLimit} entries found`);
47321
+ formatted.push(`More entries available. Use offset=${endIndex + 1} to continue.`);
47322
+ } else if (hitCollectionCap || hitFolderTruncation) {
47323
+ formatted.push("More entries may exist beyond the current truncated view.");
47194
47324
  }
47195
47325
  return formatted;
47196
47326
  }
47197
- async function collectEntries(dirPath, relativePrefix, remainingDepth, entries) {
47327
+ async function collectEntries(dirPath, relativePrefix, remainingDepth, entries, maxEntriesToCollect, maxChildrenPerDir) {
47198
47328
  const queue = [
47199
47329
  { absPath: dirPath, prefix: relativePrefix, depth: remainingDepth }
47200
47330
  ];
47331
+ let hitFolderTruncation = false;
47201
47332
  while (queue.length > 0) {
47333
+ if (entries.length >= maxEntriesToCollect) {
47334
+ return { hitCollectionCap: true, hitFolderTruncation };
47335
+ }
47202
47336
  const current = queue.shift();
47203
47337
  if (!current)
47204
47338
  break;
@@ -47238,7 +47372,28 @@ async function collectEntries(dirPath, relativePrefix, remainingDepth, entries)
47238
47372
  throw new Error(`failed to read directory: ${err}`);
47239
47373
  }
47240
47374
  dirEntries.sort((a, b) => a.entry.name.localeCompare(b.entry.name));
47241
- for (const item of dirEntries) {
47375
+ const visibleEntries = dirEntries.slice(0, maxChildrenPerDir);
47376
+ const omittedEntries = Math.max(0, dirEntries.length - visibleEntries.length);
47377
+ if (omittedEntries > 0) {
47378
+ hitFolderTruncation = true;
47379
+ const omittedSortKey = formatEntryName(`${prefix ? `${prefix}/` : ""}￿-omitted`);
47380
+ const omittedDepth = prefix ? prefix.split(path10.sep).length : 0;
47381
+ visibleEntries.push({
47382
+ absPath,
47383
+ relativePath: prefix,
47384
+ kind: "omitted",
47385
+ entry: {
47386
+ name: omittedSortKey,
47387
+ displayName: `… (${omittedEntries.toLocaleString()} more entries)`,
47388
+ depth: omittedDepth,
47389
+ kind: "omitted"
47390
+ }
47391
+ });
47392
+ }
47393
+ for (const item of visibleEntries) {
47394
+ if (entries.length >= maxEntriesToCollect) {
47395
+ return { hitCollectionCap: true, hitFolderTruncation };
47396
+ }
47242
47397
  if (item.kind === "directory" && depth > 1) {
47243
47398
  queue.push({
47244
47399
  absPath: item.absPath,
@@ -47249,6 +47404,7 @@ async function collectEntries(dirPath, relativePrefix, remainingDepth, entries)
47249
47404
  entries.push(item.entry);
47250
47405
  }
47251
47406
  }
47407
+ return { hitCollectionCap: false, hitFolderTruncation };
47252
47408
  }
47253
47409
  function formatEntryName(filePath) {
47254
47410
  const normalized = filePath.replace(/\\/g, "/");
@@ -47276,13 +47432,17 @@ function formatEntryLine(entry) {
47276
47432
  case "other":
47277
47433
  name += "?";
47278
47434
  break;
47435
+ case "omitted":
47436
+ break;
47279
47437
  default:
47280
47438
  break;
47281
47439
  }
47282
47440
  return `${indent}${name}`;
47283
47441
  }
47284
- var MAX_ENTRY_LENGTH = 500, INDENTATION_SPACES = 2;
47285
- var init_ListDirCodex2 = () => {};
47442
+ var MAX_ENTRY_LENGTH = 500, INDENTATION_SPACES = 2, DEFAULT_OFFSET = 1, DEFAULT_LIMIT2 = 25, DEFAULT_DEPTH = 2;
47443
+ var init_ListDirCodex2 = __esm(() => {
47444
+ init_directoryLimits();
47445
+ });
47286
47446
 
47287
47447
  // src/tools/schemas/LS.json
47288
47448
  var LS_default2;
@@ -47450,7 +47610,7 @@ async function memory(args) {
47450
47610
  if (existsSync13(filePath)) {
47451
47611
  throw new Error(`memory create: block already exists at ${pathArg}`);
47452
47612
  }
47453
- const limit2 = args.limit ?? DEFAULT_LIMIT2;
47613
+ const limit2 = args.limit ?? DEFAULT_LIMIT3;
47454
47614
  if (!Number.isInteger(limit2) || limit2 <= 0) {
47455
47615
  throw new Error("memory create: 'limit' must be a positive integer");
47456
47616
  }
@@ -47779,7 +47939,7 @@ function requireString(value, field, command) {
47779
47939
  }
47780
47940
  return value;
47781
47941
  }
47782
- var execFile9, DEFAULT_LIMIT2 = 2000;
47942
+ var execFile9, DEFAULT_LIMIT3 = 2000;
47783
47943
  var init_Memory2 = __esm(async () => {
47784
47944
  init_context();
47785
47945
  await init_client2();
@@ -103516,7 +103676,9 @@ function ConversationSelector2({
103516
103676
  const result = await client.conversations.list({
103517
103677
  agent_id: agentId,
103518
103678
  limit: FETCH_PAGE_SIZE3,
103519
- ...afterCursor && { after: afterCursor }
103679
+ ...afterCursor && { after: afterCursor },
103680
+ order: "desc",
103681
+ order_by: "last_run_completion"
103520
103682
  });
103521
103683
  const enrichedConversations = await Promise.all(result.map(async (conv) => {
103522
103684
  try {
@@ -135252,6 +135414,9 @@ __export(exports_memoryFilesystem2, {
135252
135414
  ensureMemoryFilesystemDirs: () => ensureMemoryFilesystemDirs2,
135253
135415
  enableMemfsIfCloud: () => enableMemfsIfCloud2,
135254
135416
  applyMemfsFlags: () => applyMemfsFlags2,
135417
+ MEMORY_TREE_MAX_LINES: () => MEMORY_TREE_MAX_LINES2,
135418
+ MEMORY_TREE_MAX_CHILDREN_PER_DIR: () => MEMORY_TREE_MAX_CHILDREN_PER_DIR2,
135419
+ MEMORY_TREE_MAX_CHARS: () => MEMORY_TREE_MAX_CHARS2,
135255
135420
  MEMORY_SYSTEM_DIR: () => MEMORY_SYSTEM_DIR2,
135256
135421
  MEMORY_FS_ROOT: () => MEMORY_FS_ROOT2,
135257
135422
  MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR2,
@@ -135280,7 +135445,7 @@ function labelFromRelativePath2(relativePath) {
135280
135445
  const normalized = relativePath.replace(/\\/g, "/");
135281
135446
  return normalized.replace(/\.md$/, "");
135282
135447
  }
135283
- function renderMemoryFilesystemTree2(systemLabels, detachedLabels) {
135448
+ function renderMemoryFilesystemTree2(systemLabels, detachedLabels, options = {}) {
135284
135449
  const makeNode = () => ({ children: new Map, isFile: false });
135285
135450
  const root = makeNode();
135286
135451
  const insertPath = (base2, label) => {
@@ -135315,20 +135480,75 @@ function renderMemoryFilesystemTree2(systemLabels, detachedLabels) {
135315
135480
  return nameA.localeCompare(nameB);
135316
135481
  });
135317
135482
  };
135318
- const lines = ["/memory/"];
135483
+ const limits = getDirectoryLimits();
135484
+ const maxLines = Math.max(2, options.maxLines ?? limits.memfsTreeMaxLines);
135485
+ const maxChars = Math.max(128, options.maxChars ?? limits.memfsTreeMaxChars);
135486
+ const maxChildrenPerDir = Math.max(1, options.maxChildrenPerDir ?? limits.memfsTreeMaxChildrenPerDir);
135487
+ const rootLine = "/memory/";
135488
+ const lines = [rootLine];
135489
+ let totalChars = rootLine.length;
135490
+ const countTreeEntries = (node) => {
135491
+ let total = 0;
135492
+ for (const [, child] of node.children) {
135493
+ total += 1;
135494
+ if (child.children.size > 0) {
135495
+ total += countTreeEntries(child);
135496
+ }
135497
+ }
135498
+ return total;
135499
+ };
135500
+ const canAppendLine = (line) => {
135501
+ const nextLineCount = lines.length + 1;
135502
+ const nextCharCount = totalChars + 1 + line.length;
135503
+ return nextLineCount <= maxLines && nextCharCount <= maxChars;
135504
+ };
135319
135505
  const render2 = (node, prefix) => {
135320
135506
  const entries = sortedEntries(node);
135321
- entries.forEach(([name, child], index) => {
135322
- const isLast = index === entries.length - 1;
135507
+ const visibleEntries = entries.slice(0, maxChildrenPerDir);
135508
+ const omittedEntries = Math.max(0, entries.length - visibleEntries.length);
135509
+ const renderItems = visibleEntries.map(([name, child]) => ({
135510
+ kind: "entry",
135511
+ name,
135512
+ child
135513
+ }));
135514
+ if (omittedEntries > 0) {
135515
+ renderItems.push({ kind: "omitted", omittedCount: omittedEntries });
135516
+ }
135517
+ for (const [index, item] of renderItems.entries()) {
135518
+ const isLast = index === renderItems.length - 1;
135323
135519
  const branch = isLast ? "└──" : "├──";
135324
- lines.push(`${prefix}${branch} ${name}${child.isFile ? "" : "/"}`);
135325
- if (child.children.size > 0) {
135520
+ const line = item.kind === "entry" ? `${prefix}${branch} ${item.name}${item.child.isFile ? "" : "/"}` : `${prefix}${branch} … (${item.omittedCount.toLocaleString()} more entries)`;
135521
+ if (!canAppendLine(line)) {
135522
+ return false;
135523
+ }
135524
+ lines.push(line);
135525
+ totalChars += 1 + line.length;
135526
+ if (item.kind === "entry" && item.child.children.size > 0) {
135326
135527
  const nextPrefix = `${prefix}${isLast ? " " : "│ "}`;
135327
- render2(child, nextPrefix);
135528
+ if (!render2(item.child, nextPrefix)) {
135529
+ return false;
135530
+ }
135328
135531
  }
135329
- });
135532
+ }
135533
+ return true;
135330
135534
  };
135331
- render2(root, "");
135535
+ const totalEntries = countTreeEntries(root);
135536
+ const fullyRendered = render2(root, "");
135537
+ if (!fullyRendered) {
135538
+ while (lines.length > 1) {
135539
+ const shownEntries = Math.max(0, lines.length - 1);
135540
+ const omittedEntries = Math.max(1, totalEntries - shownEntries);
135541
+ const notice = `[Tree truncated: showing ${shownEntries.toLocaleString()} of ${totalEntries.toLocaleString()} entries. ${omittedEntries.toLocaleString()} omitted.]`;
135542
+ if (canAppendLine(notice)) {
135543
+ lines.push(notice);
135544
+ break;
135545
+ }
135546
+ const removed = lines.pop();
135547
+ if (removed) {
135548
+ totalChars -= 1 + removed.length;
135549
+ }
135550
+ }
135551
+ }
135332
135552
  return lines.join(`
135333
135553
  `);
135334
135554
  }
@@ -135410,8 +135630,13 @@ async function enableMemfsIfCloud2(agentId) {
135410
135630
  console.warn(`Warning: Could not enable memfs for new agent: ${error instanceof Error ? error.message : String(error)}`);
135411
135631
  }
135412
135632
  }
135413
- var MEMORY_FS_ROOT2 = ".letta", MEMORY_FS_AGENTS_DIR2 = "agents", MEMORY_FS_MEMORY_DIR2 = "memory", MEMORY_SYSTEM_DIR2 = "system";
135414
- var init_memoryFilesystem2 = () => {};
135633
+ var MEMORY_FS_ROOT2 = ".letta", MEMORY_FS_AGENTS_DIR2 = "agents", MEMORY_FS_MEMORY_DIR2 = "memory", MEMORY_SYSTEM_DIR2 = "system", MEMORY_TREE_MAX_LINES2, MEMORY_TREE_MAX_CHARS2, MEMORY_TREE_MAX_CHILDREN_PER_DIR2;
135634
+ var init_memoryFilesystem2 = __esm(() => {
135635
+ init_directoryLimits();
135636
+ MEMORY_TREE_MAX_LINES2 = DIRECTORY_LIMIT_DEFAULTS.memfsTreeMaxLines;
135637
+ MEMORY_TREE_MAX_CHARS2 = DIRECTORY_LIMIT_DEFAULTS.memfsTreeMaxChars;
135638
+ MEMORY_TREE_MAX_CHILDREN_PER_DIR2 = DIRECTORY_LIMIT_DEFAULTS.memfsTreeMaxChildrenPerDir;
135639
+ });
135415
135640
 
135416
135641
  // node_modules/@letta-ai/letta-client/core/error.mjs
135417
135642
  class LettaError extends Error {
@@ -136662,7 +136887,9 @@ function ConversationSelector({
136662
136887
  const result = await client.conversations.list({
136663
136888
  agent_id: agentId,
136664
136889
  limit: FETCH_PAGE_SIZE,
136665
- ...afterCursor && { after: afterCursor }
136890
+ ...afterCursor && { after: afterCursor },
136891
+ order: "desc",
136892
+ order_by: "last_run_completion"
136666
136893
  });
136667
136894
  const enrichedConversations = await Promise.all(result.map(async (conv) => {
136668
136895
  try {
@@ -143152,4 +143379,4 @@ Error during initialization: ${message}`);
143152
143379
  }
143153
143380
  main();
143154
143381
 
143155
- //# debugId=D1C8E311510A3C4964756E2164756E21
143382
+ //# debugId=06EC6034A250F60F64756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letta-ai/letta-code",
3
- "version": "0.19.4",
3
+ "version": "0.19.5",
4
4
  "description": "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -68,7 +68,7 @@
68
68
  "fix": "bunx --bun @biomejs/biome@2.2.5 check --write src",
69
69
  "typecheck": "tsc --noEmit",
70
70
  "check": "bun run scripts/check.js",
71
- "dev": "LETTA_DEBUG=1 bun --loader:.md=text --loader:.mdx=text --loader:.txt=text run src/index.ts",
71
+ "dev": "LETTA_DEBUG=${LETTA_DEBUG:-1} bun --loader:.md=text --loader:.mdx=text --loader:.txt=text run src/index.ts",
72
72
  "build": "node scripts/postinstall-patches.js && bun run build.js",
73
73
  "test:update-chain:manual": "bun run src/tests/update-chain-smoke.ts --mode manual",
74
74
  "test:update-chain:startup": "bun run src/tests/update-chain-smoke.ts --mode startup",